#!/usr/bin/perl
use strict;
use warnings;
use FindBin qw($Bin);
use lib "$Bin/../../PerlLib";
use BRCM::GenConfig;

# $p will allow us to GET values from the PROFILE
# $c will allow us to SET (and GET and DRIVER_SETUP) on the config
# file as we transform it from a template to the final config

# arguments 
# * profile file
# * config  file
my $p    = new BRCM::GenConfig(shift);
my $chip = $p->get('BRCM_CHIP');
my $chip_rev = $p->get('BRCM_CHIP_REV');
if ($chip_rev) {
    $chip_rev = substr($chip_rev, 1, -1, '');;
}
else {
    $chip_rev = "";
}
my $c    = new BRCM::GenConfig( shift, Chip => $chip, Profile => $p );


if ( $p->get('BRCM_KERNEL_ROOTFS') eq "nfs" ) {
    $c->set( 'BRCM_DRIVER_ETHERNET', 'y' );
}


$c->set( "CONFIG_BCM9$chip", 'y' );
$c->set( "CONFIG_BCM_BOARD", 'y' );
$c->set( "CONFIG_BCM_CFE_XARGS", 'y' );
$c->set( "CONFIG_BCM_CHIP_NUMBER", $chip);
$c->set( "CONFIG_BRCM_CHIP_REV", "0x${chip}${chip_rev}");
$c->driver_setup( "BOARD", "BOARD" );
$c->set( "CONFIG_BCM_CHIPINFO", 'm' );
$c->driver_setup( "CHIPINFO", "CHIPINFO" );

if ( $p->get("BRCM_IKOS") ) {
    $c->unset("CONFIG_BCM_BOARD");
    $c->unset("CONFIG_BCM_CHIPINFO");
}

$c->set( "CONFIG_BCM_PLATFORM", 'y' );
$c->driver_setup( "PLATFORM", "PLATFORM" );

$c->set("CONFIG_EPOLL", "y");

# if ( $chip =~ /^(63268)$/ ) {
$c->driver_setup( "XTM",  "XTMCFG" );
$c->driver_setup( "XTM",  "XTMRT" );
$c->driver_setup( "ADSL", "ADSL" );
if ( $chip =~ /^(63268|63138|63148|63158|63178)$/ ) {
    $c->set( "CONFIG_BCM_DSL_GINP_RTX", $p->get("BRCM_PHY_GINP_RTX") );
}
if ( $chip eq '63138' ) {
    $c->set( "CONFIG_BCM_DSL_GFAST", $p->get("BRCM_PHY_GFAST") );
    $c->set( "CONFIG_BCM_DSL_GFASTCOMBO", $p->get("BRCM_PHY_GFASTCOMBO") );
}

if ( $chip eq '63158' ) {
    $c->set( "CONFIG_BCM_DSL_GFAST", $p->get("BRCM_PHY_GFAST") );
    $c->set( "CONFIG_BCM_DSL_GFASTCOMBO", $p->get("BRCM_PHY_GFASTCOMBO") );
    $c->set( "CONFIG_BCM_DSL_CO", $p->get("BRCM_PHY_CO") );
    $c->set( "CONFIG_BCM_55153_DPU", $p->get("BRCM_55153_DPU") );
}

$c->driver_setup( "ENET_SYSPORT", "ENET_SYSPORT" );

if ( $chip =~ /^(4908|63268)$/ ) {
    $c->set( "CONFIG_BCM_ENET_4908_GMAC", $p->get("BRCM_ENET_4908_GMAC") );
    $c->set( "CONFIG_BCM_GMAC", $p->get("BRCM_ENET_4908_GMAC") );
    $c->set( "CONFIG_BCM_ENET_MULTI_IMP_SUPPORT", $p->get("BRCM_ENET_MULTI_IMP_SUPPORT") );
}

if ( $chip eq '63158' ) {
    $c->set( "CONFIG_BCM_ENET_MULTI_IMP_SUPPORT", $p->get("BRCM_ENET_MULTI_IMP_SUPPORT") );
}

if ( $chip =~ /^(63268)$/ ) {
    $c->driver_setup( "EXT_BONDING", "EXT_BONDING" );
}


$c->driver_setup( "ETHERNET", "ENET" );
if( $p->get("BRCM_DRIVER_ETHERNET")) {
	#we can enable CONFIG_NET_SWITCHDEV for all chipsets in case of kernel greater than 4.1
	if(! defined $p->get("LINUX_4_1_0"))
	{
		$c->set( "CONFIG_NET_SWITCHDEV",'y' );
	}

}
if ( $p->get('BRCM_EXT_SWITCH') ) {
    $c->set( 'CONFIG_BCM_EXT_SWITCH',      'y' );
    $c->set( 'CONFIG_BCM_EXT_SWITCH_TYPE', $p->get('BRCM_EXT_SWITCH_TYPE') );
    if ( $p->get('BRCM_PORTS_ON_INT_EXT_SW') ) {
        $c->set( 'CONFIG_BCM_PORTS_ON_INT_EXT_SW', 'y');
    }
}
if ( $p->get("BUILD_ETHWAN") ) {
    $c->set( "CONFIG_BCM_ETHWAN",         "y" );
}
if ( $p->get('BRCM_PHY_54616') ) {
    $c->set( 'CONFIG_BCM_PHY_54616', 'y' );
}


if ( $chip eq '63268' ) {
    if ( $p->get("BRCM_GMAC") ) {
        $c->set( 'CONFIG_BCM_GMAC', 'y' );
    }
}


if ( $p->get('BCM_JUMBO_FRAME') ) {
    $c->set( 'CONFIG_BCM_JUMBO_FRAME', 'y' );
    if ( $p->get('BCM_MAX_MTU_SIZE') ) {
        $c->set( "CONFIG_BCM_MAX_MTU_SIZE", $p->get("BCM_MAX_MTU_SIZE") );
    }
    if ( $p->get('BCM_USER_DEFINED_DEFAULT_MTU') ) {
        $c->set( 'CONFIG_BCM_USER_DEFINED_DEFAULT_MTU', 'y' );
        $c->set( 'CONFIG_BCM_USER_DEFINED_DEFAULT_MTU_SIZE', $p->get('BCM_USER_DEFINED_DEFAULT_MTU_SIZE') );
    }
    if ( $p->get('BCM_IGNORE_BRIDGE_MTU') ) {
        $c->set( 'CONFIG_BCM_IGNORE_BRIDGE_MTU', 'y' );
    }
}


$c->driver_setup( 'VLAN',  'VLAN' );
if ( $p->get("BUILD_VLAN_AGGR") ) {
    $c->set( "CONFIG_BCM_VLAN_AGGREGATION",         "y" );
}
if ( $p->get("BRCM_VLAN_ROUTED_WAN_USES_ROOT_DEV_MAC") ) {
    $c->set( "CONFIG_BCM_VLAN_ROUTED_WAN_USES_ROOT_DEV_MAC",         "y" );
}

$c->driver_setup( 'USB',   'USB' );
$c->driver_setup( 'LOG',   'LOG' );
$c->driver_setup( 'LASER', 'LASER' );


$c->driver_setup( "TMS", "TMS" );
if ( $p->get("BUILD_TMS") ) {
    $c->set( "CONFIG_BCM_TMS", 'm' );
}

if ( $p->get("BUILD_BRCM_XDSL_DISTPOINT") ) {
    $c->set( "CONFIG_BCM_FTTDP", "y");
    $c->set( "CONFIG_BCM_FTTDP_G9991", $p->get("BRCM_XDSL_DISTPOINT_USE_G9991") );
}

if ( $chip =~ /^(6838|6848|6858|63158|6846|6856|6878|6855)$/ ) {
	$c->set( "CONFIG_BCM_MAX_GEM_PORTS", $p->get("BCM_MAX_GEM_PORTS") );
}
else {
	$c->set( "CONFIG_BCM_MAX_GEM_PORTS", 32);
}

if ( $chip =~ /^(63268|63138|63148|6838|6848|6858|4908|63158|6846|6856|6878|6855)$/ ) {
    $c->driver_setup( "MoCA", "MoCA" );

    if ( $p->get("BUILD_6802_MOCA") ) {
        $c->set( "CONFIG_BCM_6802_MoCA", "y" );
    }

    if ( $p->get("BRCM_MOCA_AVS") ) {
        $c->set( "CONFIG_BCM_MoCA_AVS", "y" );
    }

}

if ( $chip =~ /^(6838|6848|63138|63148|6858|4908|63158|47622|6846|6856|6878|6855)$/ ) {
    $c->driver_setup( "I2C", "I2C_BUS" );
    $c->driver_setup( "I2C", "I2C_CHIP" );
    if ( $p->get("BRCM_DRIVER_I2C") ) {
        $c->set( "CONFIG_I2C",         "y" );
        $c->set( "CONFIG_I2C_CHARDEV", "y" );
        if ( $chip =~ /^(6838|6848|6858|6846|6856|6878|6855)$/ ) {
            $c->set( 'CONFIG_ARCH_REQUIRE_GPIOLIB', 'y' );
		    $c->set( "CONFIG_GPIOLIB",     'y' );
		    $c->set( "CONFIG_I2C_MUX", 'y');
		    $c->set( "CONFIG_I2C_MUX_PCA954x", 'y');
        }
    }
    $c->driver_setup( "OPTICALDET", "OPTICALDET" );
    $c->driver_setup( "SMTC", "SMTC" );
}

if ( $chip =~ /^(63178)$/ ) {
    $c->driver_setup( "I2C", "I2C_BUS" );
    if ( $p->get("BRCM_DRIVER_I2C") ) {
        $c->set( "CONFIG_BCM_I2C_GPIO","y" );
        $c->set( "CONFIG_GPIOLIB",     "y" );
        $c->set( "CONFIG_I2C",         "y" );
        $c->set( "CONFIG_I2C_ALGOBIT", "y" );
        $c->set( "CONFIG_I2C_GPIO",    "y" );
        $c->set( "CONFIG_I2C_CHARDEV", "y" );
    }
}

if ( $chip =~ /^(6858|6856|6846|6878|6855)$/ ) {
    if ( $p->get( "BRCM_PON_WAN_TYPE_AUTO_DETECT" ) ) {
        $c->set( "CONFIG_BCM_PON_WAN_TYPE_AUTO_DETECT", "y" );
    }
}

if ( $chip =~ /^(6858|6856|63158|6855)$/ ) {
    if ( $p->get( "BUILD_NGPON_AMD2" ) ) {
        $c->set( "CONFIG_BCM_BUILD_NGPON_AMD2", "y" );
    }
}

$c->driver_setup( "I2S", "I2S" );
if ( $p->get("BRCM_DRIVER_I2S") ) {
    $c->set( "CONFIG_I2S",         "y" );
}
$c->driver_setup( "BLUETOOTH_USB", "BLUETOOTH_USB" );
$c->driver_setup( "NFC", "NFC_I2C" );
if ( $p->get("BRCM_DRIVER_NFC") ) {
    $c->set( "CONFIG_I2C_ALGOBIT", "y" );
}

if ( $chip =~ /^(63138|47622|4908|63158|63178|6858|6846|6856|6878|6855)$/ ) {
    $c->driver_setup( "HS_UART", "HS_UART" );
}

if ( $p->get("BRCM_DRIVER_WDT") ) {
    $c->set( "CONFIG_WATCHDOG", 'y' );
    $c->set( "CONFIG_WATCHDOG_CORE", 'y' );
    $c->set( "CONFIG_BCM96XXX_WDT", 'y' );
}

if ( $chip =~ /^(63138|4908|6858|63158|6856|47622|6855)$/ ) {
    if ( $p->get("BRCM_DRIVER_EMMC") ) {
	$c->set( "CONFIG_MMC", 'y' );
	$c->set( "CONFIG_GPIOLIB", 'y' );
	$c->set( "CONFIG_MMC_BLOCK", 'y' );
	$c->set( "CONFIG_MMC_BLOCK_MINORS", '32' );
	$c->set( "CONFIG_MMC_SDHCI", 'y' );
	$c->set( "CONFIG_MMC_SDHCI_PLTFM", 'y' );
	$c->set( "CONFIG_MMC_SDHCI_IO_ACCESSORS", 'y' );
	$c->set( "CONFIG_MMC_SDHCI_BCM63xx", 'y' );
#	$c->set( "CONFIG_MMC_DEBUG", 'y' );
#	$c->set( "CONFIG_MMC_TEST", 'y' );
    }
    if ( $p->get("BRCM_FLASH_EMMC_ROOTFS_EXT4") ) {
    $c->set( "CONFIG_EXT4_FS",  "y" );
    $c->set( "CONFIG_EXT4_USE_FOR_EXT23",  "y" );
    $c->set( "CONFIG_EXT4_FS_XATTR",  "y" );
    $c->set( "CONFIG_EXT4_FS_POSIX_ACL",  "y" );
    $c->set( "CONFIG_EXT4_FS_SECURITY",  "y" );
    $c->set( "CONFIG_EXT4_DEBUG",  "n" );
    }
}

if ( $p->get("BUILD_MODSW_EE") ) {
    $c->set( "CONFIG_EXT4_FS",  "y" );
    $c->set( "CONFIG_EXT4_USE_FOR_EXT23",  "y" );
    $c->set( "CONFIG_EXT4_FS_XATTR",  "y" );
    $c->set( "CONFIG_EXT4_FS_POSIX_ACL",  "y" );
    $c->set( "CONFIG_EXT4_FS_SECURITY",  "y" );
    $c->set( "CONFIG_EXT4_DEBUG",  "n" );
}

$c->driver_setup( "PWRMNGT", "PWRMNGT" );


if ( $chip =~ /^(63268|63381)$/ ) {
    $c->driver_setup( "ARL", "ARL" );
}


# FIXME -- do we ever need to take the default from the template?
if ( my $i = $p->get("BCM_DEF_NR_RX_DMA_CHANNELS") ) {
    $c->set( "CONFIG_BCM_DEF_NR_RX_DMA_CHANNELS", $i );
}
if ( my $i = $p->get("BCM_DEF_NR_TX_DMA_CHANNELS") ) {
    $c->set( "CONFIG_BCM_DEF_NR_TX_DMA_CHANNELS", $i );
}

if ( $p->get("BUILD_EPON_SDK") ) {
    $c->set( "CONFIG_EPON_SDK", "y" );
    if ( $p->get("BUILD_EPON_SDK_VOICE_OAM") ) {
        $c->set( "CONFIG_EPON_SDK_VOICE_OAM", "y" );
    }
    if ( my $i = $p->get("EPON_ONU_TYPE") ) {
        $c->set( "CONFIG_$i", "y" );
    }
    if ( $p->get("EPON_UNI_UNI_ENABLED") ) {
        $c->set( "CONFIG_EPON_UNI_UNI_ENABLED", "y" );
    }
    if ( $p->get("EPON_DS_DLF_FORWARD") ) {
        $c->set( "CONFIG_EPON_DS_DLF_FORWARD", "y" );
    }

}

$c->driver_setup( "EPON_STACK", "EPON_STACK" );
if ( $p->get("BRCM_DRIVER_EPON_STACK") ) {
    if ( $p->get("EPON_CLOCK_TRANSPORT") ) {
         $c->set( "CONFIG_EPON_CLOCK_TRANSPORT", "y" );
    }
    if ( $p->get("EPON_10G_SUPPORT") ) {
         $c->set( "CONFIG_EPON_10G_SUPPORT", "y" );
    }
}

if ( ($chip =~ /^(63138|4908)$/ ) && $p->get("BRCM_DRIVER_M2M_DMA") ) {
    $c->set( "CONFIG_BCM_M2M_DMA", 'y' );
}

$c->set( "CONFIG_BCM_RECVFILE",    $p->get("BUILD_BCM_RECVFILE") );
$c->set( "CONFIG_BCM_SPEEDYGET",    $p->get("BCM_SPEEDYGET") );

if ( $p->get("BUILD_MPTCP") ) {
	$c->set( "CONFIG_BCM_MPTCP", 'y' );
	$c->set( "CONFIG_MPTCP", 'y' );

	$c->set( "CONFIG_MPTCP_PM_ADVANCED", 'y' );
	$c->set( "CONFIG_MPTCP_FULLMESH", 'y' );

	$c->set( "CONFIG_TCP_CONG_ADVANCED", 'y' );
	$c->set( "CONFIG_TCP_CONG_LIA", 'y' );
	$c->set( "CONFIG_TCP_CONG_OLIA", 'y' );

	$c->set( "CONFIG_IP_ADVANCED_ROUTER", 'y' );
}

$c->driver_setup( "PKTFLOW", "PKTFLOW" );
if ( $p->get("BRCM_DRIVER_PKTFLOW") ) {
    $c->set( "CONFIG_BLOG",       'y' );
    $c->set( "CONFIG_BLOG_IPV6",  $p->get("BRCM_DRIVER_PKTFLOW_IPV6") );
    $c->set( "CONFIG_BLOG_MCAST", $p->get("BRCM_DRIVER_PKTFLOW_MCAST") );
    $c->set( "CONFIG_BLOG_GRE",   $p->get("BRCM_DRIVER_PKTFLOW_GRE") );
    $c->set( "CONFIG_BLOG_L2TP",   $p->get("BRCM_DRIVER_PKTFLOW_L2TP") );   
    $c->set( "CONFIG_BCM_PKTFLOW_MAX_FLOWS", $p->get("BRCM_PKTFLOW_MAX_FLOWS") );
    $c->set( "CONFIG_BCM_PKTFLOW_MAX_FDB", $p->get("BRCM_PKTFLOW_MAX_FDB") );
    $c->set( "CONFIG_BCM_PKTFLOW_MAX_HOST_DEV", $p->get("BRCM_PKTFLOW_MAX_HOST_DEV") );
    $c->set( "CONFIG_BCM_PKTFLOW_MAX_HOST_MAC", $p->get("BRCM_PKTFLOW_MAX_HOST_MAC") );

    if ( $p->get("BRCM_DRIVER_PKTFLOW_FEATURE") ) {
        $c->set( "CONFIG_BLOG_FEATURE",              "y" );
        $c->set( "CONFIG_NETFILTER_XT_MATCH_LENGTH", "y" );
    }
    if ( $chip =~ /^(63148|63138|63268|6838|6848|4908|6858|63158|6846|6856|47622|63178|6878|6855)$/ ) {
        $c->set( "CONFIG_BCM_FHW", "y" );
    }
    $c->setup_impl("FHW");
    if ( $chip =~ /^(63148|63138|6838|6848|4908|6858|63158|6846|6856|6878|6855)$/ ) {
        $c->driver_setup( "PKTRUNNER", "PKTRUNNER" );

        if ( $chip =~ /^(63148|63138|4908|63158|6838|6848|6858|6846|6856|6878)$/ ) {
            if ( $p->get("BRCM_DRIVER_PKTRUNNER_GSO") ) {
                $c->set( "CONFIG_BCM_PKTRUNNER_GSO",  "y" );
            }
            if ( $p->get("BRCM_DRIVER_DHD_RUNNER_GSO") ) {
                $c->set( "CONFIG_BCM_DHD_RUNNER_GSO",  "y" );
            }
            if ( $chip =~ /^(63148|63138|4908|63158|6858|6846|6856|6878)$/ ) {
                if ( $p->get("BRCM_CSO") ) {
                    $c->set( "CONFIG_BCM_CSO",  "y" );
                }
            }
            if ( ($chip eq '4908' ) && $p->get('BUILD_HND_EAP') ) {
                if ( $p->get("BRCM_CAPWAP") ) {
                    $c->set( "CONFIG_BCM_CAPWAP",  "y" );
                }
            }
        }
    }

    if ( $chip =~ /^(47622|63178)$/ ) {
        $c->driver_setup( "ARCHER", "ARCHER" );
        if ( $p->get("BUILD_BCM_PKTFWD") && $p->get("BRCM_DRIVER_ARCHER_WLAN") ) {
            $c->set( "CONFIG_BCM_ARCHER_WLAN",  "y" );
        }
        if ( $p->get("BRCM_DRIVER_ARCHER_GSO") ) {
            $c->set( "CONFIG_BCM_ARCHER_GSO",  "y" );
        }
        $c->set( "CONFIG_BCM_ARCHER_CPU_AFFINITY", $p->get("BRCM_ARCHER_CPU_AFFINITY") );
        if ( $p->get("BRCM_DRIVER_ARCHER") ) {
            $p->set("BRCM_DRIVER_LICENSE", "m");
            if ( $p->get("BRCM_CSO") ) {
                $c->set( "CONFIG_BCM_CSO",  "y" );
            }
        }
        if ( $p->get("BRCM_DRIVER_ARCHER_SIM") ) {
            $c->set( "CONFIG_BCM_ARCHER_SIM",  "y" );
        }
    }
    if ( $chip =~ /^(63148|63138|4908|63158|63268|47622|63178)$/ ) {
        $c->driver_setup( "CMDLIST", "CMDLIST" );
        if ( $p->get("BRCM_DRIVER_CMDLIST_SIM") ) {
            $c->set( "CONFIG_BCM_CMDLIST_SIM",  "y" );
        }
    }
    if ( $p->get("BRCM_OVS_SUPPORT") ) {
		if ( $chip =~ /^(63148|63138|4908|6858|63158|6846|6856|6878|47189|47622|63178)$/ ) {
			$c->set( "CONFIG_BCM_OVS",   $p->get("BRCM_OVS_SUPPORT") ); 
            if ( $p->get("BRCM_OVS_SUPPORT_MCAST") ) {         
			    $c->set( "CONFIG_BCM_OVS_MCAST",   "y"); 
            }
            $p->set("BRCM_DRIVER_LICENSE", "m");
		}
	}
}

if ( $chip =~ /^(63158|6858|6856|63138|63148|4908|6846|6878)$/ ) {
	if ( $p->get("BRCM_DRIVER_SW_GSO") ) {
		$c->set( "CONFIG_BCM_SW_GSO",  "y" );
	}
}

$c->driver_setup( "LTE", "LTE" );
if ( $p->get("BRCM_DRIVER_LTE") ) {
    $c->set( "CONFIG_PHONET",  "y" );
    $c->set( "CONFIG_MHI",  "y" );
    $c->set( "CONFIG_MHI_L2MUX",  "y" );
    $c->set( "CONFIG_MHI_L3MHI",  "y" );
    $c->set( "CONFIG_MHI_L3PHONET",  "y" );
    $c->set( "CONFIG_MHI_L3MHDP",  "y" );
    $c->set( "CONFIG_BCM_LTE_PCI", $p->get("BRCM_DRIVER_LTE_PCI") );
    $c->set( "CONFIG_BCM_LTE_PCI_MODEM_BOOT", $p->get("BRCM_DRIVER_LTE_PCI_MODEM_BOOT") );
    if ( !$p->get("BRCM_DRIVER_LTE_PCI_MODEM_BOOT") ) {
        $c->set( "CONFIG_FW_LOADER",  "y" );
    }
    $c->set( "CONFIG_BCM_LTE_USB", $p->get("BRCM_DRIVER_LTE_USB") );
#    $c->set( "CONFIG_FW_LOADER",  "y" );
#    $c->set( "CONFIG_FIRMWARE_IN_KERNEL",  "n" );
#    $c->set( "CONFIG_EXTRA_FIRMWARE",  " ");
#    $c->set( "CONFIG_EXT4_FS",  "y" );
#    $c->set( "CONFIG_EXT4_USE_FOR_EXT23",  "n" );
#    $c->set( "CONFIG_EXT4_FS_XATTR",  "y" );
#    $c->set( "CONFIG_EXT4_FS_POSIX_ACL",  "y" );
#    $c->set( "CONFIG_EXT4_FS_SECURITY",  "y" );
#    $c->set( "CONFIG_EXT4_DEBUG",  "n" );
#    $c->set( "CONFIG_JBD2_DEBUG",  "n" );
#    $c->set( "CONFIG_ARCH_SUPPORTS_MSI",  "y" );
#    $c->set( "CONFIG_PCI_MSI",  "y" );
}

$c->driver_setup( "FAP", "FAP" );
if ( $p->get("BRCM_DRIVER_FAP")) {
    if ( $p->get("BRCM_DRIVER_BPM")) {
        $c->set( "CONFIG_BCM_FAP_GSO", $p->get("BRCM_DRIVER_FAP_GSO") );
        if ( $p->get("BRCM_DRIVER_FAP_GSO")) {
            $c->set( "CONFIG_BCM_FAP_GSO_LOOPBACK", $p->get("BRCM_DRIVER_FAP_GSO_LOOPBACK"));
        }
    }

    if ( $p->get("BRCM_DRIVER_FAP_LAYER2") ) {
        $c->set( "CONFIG_BCM_FAP_LAYER2", "y" );
    }
    if ( $p->get("BRCM_DRIVER_PKTFLOW_IPV6") && $p->get("BUILD_IPV6") ) {
        $c->set( "CONFIG_BCM_FAP_IPV6",  "y" );
    }
}

if ( $chip =~ /^(63268|60333|63381|47189)$/ ) {
    print "\e[0;31m PKTDMA Build Enabled \e[0m\n";
    $c->set( "CONFIG_BCM_PKTDMA", "y" );
}
elsif ( $chip =~ /^(4908)$/ ) {
    if ( $p->get("BRCM_ENET_4908_GMAC") ) {
        print "\e[0;31m PKTDMA Build Enabled \e[0m\n";
        $c->set( "CONFIG_BCM_PKTDMA", "y" );
    }
}

if ( $p->get("BRCM_DRIVER_RTP_SEQ_CHECK") ) {
    $c->set( "CONFIG_BCM_RTP_SEQ_CHECK",  "y" );
}

# setup_impl is only to emulate the logic of old gendefconifg --
# FIXME -- remove setup_impl aftre transition is done
$c->setup_impl("PKTDMA");

$c->driver_setup( "FBOND", "FBOND" );

$c->set( "CONFIG_BCM_SPU", $p->get("BRCM_DRIVER_SPU") );
$c->set( "CONFIG_BCM_CRYPTODEV", $p->get("BUILD_CRYPTODEV_LINUX") );
if ( $p->get("BRCM_DRIVER_TRNG") ) {
    $c->set( "CONFIG_HW_RANDOM", "y" );
    $c->set( "CONFIG_HW_RANDOM_IPROC_RNG200", "y" );
}

$c->driver_setup( "INGQOS", "INGQOS" );


$c->driver_setup( "BPM", "BPM" );
# BRCM_BUF_MEM_PRCNT - for backward compatibility to use static mode
$c->set( "CONFIG_BCM_BPM_BUF_MEM_PRCNT", $p->get("BRCM_BUF_MEM_PRCNT") );
$c->set( "CONFIG_BCM_BPM_DYNAMIC", $p->get("BRCM_BPM_DYNAMIC") );
$c->set( "CONFIG_BCM_BPM_DYNAMIC_TYPE_PRCNT", $p->get("BRCM_BPM_DYNAMIC_TYPE_PRCNT") );
$c->set( "CONFIG_BCM_BPM_DYNAMIC_TYPE_ABS", $p->get("BRCM_BPM_DYNAMIC_TYPE_ABS") );
$c->set( "CONFIG_BCM_BPM_DYNAMIC_PRCNT_MAX_BUF", $p->get("BRCM_BPM_DYNAMIC_PRCNT_MAX_BUF") );
$c->set( "CONFIG_BCM_BPM_DYNAMIC_PRCNT_INIT_BUF", $p->get("BRCM_BPM_DYNAMIC_PRCNT_INIT_BUF") );
$c->set( "CONFIG_BCM_BPM_DYNAMIC_ABS_MAX_BUF", $p->get("BRCM_BPM_DYNAMIC_ABS_MAX_BUF") );
$c->set( "CONFIG_BCM_BPM_DYNAMIC_ABS_INIT_BUF", $p->get("BRCM_BPM_DYNAMIC_ABS_INIT_BUF") );
$c->set( "CONFIG_BCM_BPM_DYNAMIC_AVAIL_LOW_TH", $p->get("BRCM_BPM_AVAIL_LOW_TH") );
$c->set( "CONFIG_BCM_BPM_DYNAMIC_EXPAND_STEP_SIZE", $p->get("BRCM_BPM_EXPAND_STEP_SIZE") );
$c->set( "CONFIG_BCM_BPM_DYNAMIC_SHRINK_STEP_SIZE", $p->get("BRCM_BPM_SHRINK_STEP_SIZE") );
$c->set( "CONFIG_BCM_BPM_BUF_TRACKING", $p->get("BRCM_BPM_BUF_TRACKING") );

$c->set( "CONFIG_BCM_FEED_RING_DYNAMIC", $p->get("BCM_FEED_RING_DYNAMIC") );
$c->set( "CONFIG_BCM_FEED_RING_SIZE", $p->get("BCM_FEED_RING_SIZE") );
$c->set( "CONFIG_BCM_FEED_RING_ALLOC_START", $p->get("BCM_FEED_RING_ALLOC_START") );
$c->set( "CONFIG_BCM_FEED_RING_ALLOC_BATCH", $p->get("BCM_FEED_RING_ALLOC_BATCH") );
$c->set( "CONFIG_BCM_FEED_RING_REFILL_EVERY", $p->get("BCM_FEED_RING_REFILL_EVERY") );
$c->set( "CONFIG_BCM_FEED_RING_MAX_ALLOCATIONS", $p->get("BCM_FEED_RING_MAX_ALLOCATIONS") );

$c->driver_setup( "TM", "TM" );
 
# $c->driver_setup("PWRMNGT","PWRMNGT"); # FIXME - Duplicate


$c->set( "CONFIG_BCM_CPLD1",    $p->get("BRCM_STANDBY") );
$c->set( "CONFIG_BCM_PLC_BOOT", $p->get("BUILD_HOMEPLUG") );

$c->set( "CONFIG_BCM_IEEE1905", $p->get("BUILD_IEEE1905") );

$c->driver_setup( "ISDN", "ISDN" );
if ( $p->get("BRCM_DRIVER_ISDN") ) {
    $c->set( "CONFIG_BCM_ISDN",             "y" );
    $c->set( "CONFIG_ISDN",                 "m" );
    $c->set( "CONFIG_ISDN_CAPI",            "m" );
    $c->set( "CONFIG_ISDN_CAPI_MIDDLEWARE", "y" );
    $c->set( "CONFIG_ISDN_CAPI_CAPI20",     "m" );
}

$c->driver_setup( "DPI", "DPI" );
if ( $p->get("BRCM_DRIVER_DPI") ) {
    $c->set( "CONFIG_BCM_DPI_TEST",    $p->get("BRCM_DPI_TEST") );
    $c->set( "CONFIG_BCM_DPI_QOS",     $p->get("BRCM_DRIVER_DPI_QOS") );
    if ( $p->get("BRCM_DRIVER_DPI_WLAN_QOS") ) {
       $c->set( "CONFIG_BCM_DPI_WLAN_QOS", "y" );
    }
    $c->set( "CONFIG_BCM_DPI_QOS_CPU", $p->get("BRCM_DRIVER_DPI_QOS_CPU") );
}

$c->set( "CONFIG_BCM_VOICE_SUPPORT", $p->get("BRCM_VOICE_SUPPORT") );
if ( $p->get("BRCM_VOICE_SUPPORT") ) {
   $c->set( "CONFIG_BCM_SLICSLAC",          "m" );
   $c->setup_impl("SLICSLAC");
   $c->set( "CONFIG_BCM_DSPHAL",            "m" );
   $c->setup_impl("DSPHAL");
   $c->set( "CONFIG_EPOLL",                 "y" );
   $c->set( "CONFIG_BCM_PRINTK_INT_ENABLED","y");
}

$c->set( "CONFIG_BCM_DECT_SUPPORT", $p->get("BRCM_VOICE_DECT_SUPPORT") );
if ( $p->get("BRCM_VOICE_DECT_SUPPORT") ) {
   $c->set( "CONFIG_BCM_DECT",               "m" );
   $c->setup_impl("DECT");
   $c->set( "CONFIG_BCM_PRINTK_INT_ENABLED", "y");
}

$c->driver_setup( "BCMPROF", "BCMPROF" );
$c->driver_setup( "PROCFS",  "PROCFS" );
$c->driver_setup( "SERIAL",  "SERIAL" );
if ( $p->get("BRCM_DRIVER_SERIAL") ) {
     $c->set( "CONFIG_BCM_SERIAL_CONSOLE", "y" );
}
if ( $p->get("ARM_PL011_SERIAL") ) {

     $c->set( 'CONFIG_SERIAL_AMBA_PL011',               'y' );
     $c->set( 'CONFIG_SERIAL_AMBA_PL011_CONSOLE',       'y' );

     if($p->get('KERNEL_ARCH') eq "arm") {
         $c->unset("CONFIG_DEBUG_LL_UART_NONE");
         $c->set( 'CONFIG_ARM_AMBA',                    'y' );
         $c->set( "CONFIG_DEBUG_LL_UART_PL01X",		"y" );
         $c->set( "CONFIG_DEBUG_UART_PHYS",		"0xff812000" );
         $c->set( "CONFIG_DEBUG_UART_VIRT",		"0xf0812000" );
     }
}

if ( $p->get("BRCM_KTOOLS") ) {
    $c->set( "CONFIG_BRCM_KTOOLS", "y" );
}


$c->set( "CONFIG_BCM_LIBS", 'm' );

if ( $p->get("BUILD_BUZZZ") ) {
    $c->set( "CONFIG_BUZZZ", 'y' );
   if ( $p->get("BUZZZ_FUNC") ) {
      $c->set( "CONFIG_BUZZZ_FUNC", "y" );
   }
   if ( $p->get("BUZZZ_PMON") ) {
      $c->set( "CONFIG_BUZZZ_PMON", "y" );
   }
   if ( $p->get("BUZZZ_KEVT") ) {
      $c->set( "CONFIG_BUZZZ_KEVT", "y" );
   }
}

$c->driver_setup( "SPDSVC", "SPDSVC" );

$c->driver_setup( "SPDTEST", "SPDTEST" );

if ( $p->get("BRCM_DRIVER_SPDTEST") ) {
    $p->set("BRCM_DRIVER_LICENSE", "m");
}

$c->driver_setup( "LICENSE", "LICENSE" );

if ( $p->get("BRCM_KERNEL_FTRACE") ) {
    $c->set(
        [
            qw[
              CONFIG_TRACEPOINTS CONFIG_MARKERS
              CONFIG_NOP_TRACER CONFIG_TRACER_MAX_TRACE CONFIG_RING_BUFFER
              CONFIG_TRACING CONFIG_SCHED_TRACER CONFIG_CONTEXT_SWITCH_TRACER
              CONFIG_EVENT_TRACER CONFIG_BINARY_PRINTF
              ]
        ],
        'y'
    );
}

if ( $p->get("BRCM_KERNEL_PREEMPTIRQSOFF_TRACE") ) {
    $c->set(
        [
            qw[
              CONFIG_IRQSOFF_TRACER CONFIG_PREEMPT_TRACER
              ]
        ],
        'y'
    );
}

if ( $p->get("BRCM_KERNEL_FUNCTION_TRACE") ) {
    $c->set(
        [
            qw[
              CONFIG_FUNCTION_TRACER CONFIG_FUNCTION_GRAPH_TRACER
              CONFIG_STACKTRACE
              ]
        ],
        'y'
    );
}


$c->set( "CONFIG_KALLSYMS", $p->get("BRCM_KERNEL_KALLSYMS") );
if ( $p->get("BRCM_KERNEL_DEBUG") ) {
    $c->set( "CONFIG_REMOTE_DEBUG", "y" );
    $c->set( "CONFIG_GDB_CONSOLE",  "y" );
}
$c->set( "CONFIG_BCM_COLORIZE_PRINTS", $p->get("BCM_COLORIZE_PRINTS") );
$c->set( "CONFIG_BCM_ASSERTS",         $p->get("BCM_ASSERTS") );
$c->set( "CONFIG_BCM_FATAL_ASSERTS",   $p->get("BCM_FATAL_ASSERTS") );
$c->set( "CONFIG_DEBUG_KERNEL",        $p->get("BCM_KERNEL_HACKING") );


if ( $p->get("BCM_DEBUG_SPINLOCK") ) {
    $c->set( "CONFIG_DEBUG_SPINLOCK",       "y" );
    $c->set( "CONFIG_DEBUG_SPINLOCK_SLEEP", "y" );
}
$c->set( "CONFIG_DEBUG_MUTEXES", $p->get("BCM_DEBUG_MUTEXES") );
$c->set( "CONFIG_RCU_CPU_STALL_DETECTOR",
    $p->get("BCM_RCU_CPU_STALL_DETECTOR") );
$c->set( "CONFIG_DEBUG_PREEMPT", $p->get("BCM_DEBUG_PREEMPT") );
$c->set( "CONFIG_DETECT_HUNG_TASK", $p->get("BCM_DETECT_HUNG_TASK") );

if ( $p->get("BCM_DEBUG_SLAB") ) {
    $c->set( "CONFIG_DEBUG_SLAB",      "y" );
    $c->set( "CONFIG_DEBUG_SLAB_LEAK", "y" );
}

$c->set( "CONFIG_SCHEDSTATS",    $p->get("BCM_SCHEDSTATS") );
$c->set( "CONFIG_SCHED_DEBUG",   $p->get("BCM_SCHED_DEBUG") );
$c->set( "CONFIG_DEBUG_ATOMIC_SLEEP", $p->get("BCM_DEBUG_ATOMIC_SLEEP") );

if ( $p->get("BCM_MAGIC_SYSRQ") ) {
    $c->set( "CONFIG_MAGIC_SYSRQ", "y" );
    $c->set( "CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE", '0x1' );
}

if ( $p->get("BCM_FAILSAFE_BOOT") ) {
    $c->set( "CONFIG_BCM_FAILSAFE_BOOT", "y" );
}

$c->set( "CONFIG_BRCM_VMTOOLS", $p->get("BRCM_KERNEL_VMTOOLS") );
$c->set( "CONFIG_BRCM_CSTAT",   $p->get("BRCM_KERNEL_CSTAT") );
if ( $p->get("ENABLE_APP_COREDUMPS") ) {
    $c->set( "CONFIG_ELF_CORE",                      "y" );
    $c->set( "CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS", "y" );
}

if ( $p->get("BRCM_IKOS") ) {
   $c->set( "CONFIG_BRCM_IKOS", 'y' );
}

if ( $p->get("BRCM_QEMU") ) {
   $c->set( "CONFIG_BRCM_QEMU", 'y' );
}

if ( $p->get("BP_PHYS_INTF") ) {
   $c->set( "CONFIG_BP_PHYS_INTF", 'y' );
}

$c->set( "CONFIG_SMP", 'y' );
$c->unset("CONFIG_KLOB");
if ( $chip =~ /^(63138)$/ ) {
    $c->set( "CONFIG_PLAT_CA9_SMP", 'y' );
}
if ( $chip =~ /^(63148)$/ ) {
    $c->set( "CONFIG_PLAT_B15_SMP", 'y' );
}
if ( $chip =~ /^(47189|6846)$/ ) {
    $c->set( "CONFIG_PLAT_CA7_SMP", 'y' );
}
if ( $p->get("BRCM_KERNEL_PREEMPT") ) {
    $c->unset("CONFIG_PREEMPT_NONE");
    $c->unset("CONFIG_PREEMPT_VOLUNTARY");
       # 3.14 does not have RT PREEMPT
       $c->set( "CONFIG_PREEMPT", 'y' );
}
$c->set( "CONFIG_BCM_SCHED_RT_PERIOD",  $p->get("BRCM_SCHED_RT_PERIOD") );
$c->set( "CONFIG_BCM_SCHED_RT_RUNTIME", $p->get("BRCM_SCHED_RT_RUNTIME") );
$c->set( "CONFIG_BCM_SCHED_RT_SHARE",   $p->get("BRCM_SCHED_RT_SHARE") );
$c->set( "CONFIG_BCM_PROC_CPU_AFFINITY_HINT", $p->get("BRCM_PROC_CPU_AFFINITY_HINT") );
$c->set( "CONFIG_HIGH_RES_TIMERS", $p->get("BRCM_CONFIG_HIGH_RES_TIMERS") );
$c->set( "CONFIG_BCM_HARDIRQ_COUNT_CYCLES",
    $p->get("BCM_HARDIRQ_COUNT_CYCLES") );
if ( $p->get("BCM_CGROUPS") ) {
    $c->set(
        [
            qw[
              CONFIG_CGROUPS CONFIG_CGROUP_SCHED CONFIG_GROUP_SCHED CONFIG_FAIR_GROUP_SCHED CONFIG_RT_GROUP_SCHED
              CONFIG_RESOURCE_COUNTERS CONFIG_CGROUP_MEM_RES_CTLR CONFIG_MM_OWNER
              ]
        ],
        'y'
    );
}
$c->set( "CONFIG_CGROUP_BCM", $p->get("BCM_CGROUP_BCM") );

$c->set( "CONFIG_BCM_WAN_2_WAN_FWD_ENABLED", $p->get("BRCM_WAN_2_WAN_FWD_ENABLED") );

$c->set( "CONFIG_BCM_KERNEL_BONDING", $p->get("BRCM_KERNEL_BONDING") );

$c->set( "CONFIG_BCM_RUNNER_FLOODING", $p->get("BRCM_RUNNER_FLOODING") );

$c->set( "CONFIG_BCM_ROOTFS_SQUASHFS_HASH", $p->get("BUILD_ROOTFS_SQUASHFS_HASH"));

if ( $p->get("BRCM_KERNEL_CRYPTO") ) {
    $c->set(
        [
            qw[CONFIG_NET_KEY CONFIG_INET_AH CONFIG_INET_ESP
              CONFIG_INET_XFRM_TUNNEL CONFIG_INET_TUNNEL
              CONFIG_INET_XFRM_MODE_TRANSPORT
              CONFIG_INET_XFRM_MODE_TUNNEL CONFIG_XFRM_USER CONFIG_CRYPTO]
        ],
        'y'
    );
    foreach my $t (qw[HMAC NULL MD5 SHA1 DES AES]) {
        $c->set( "CONFIG_CRYPTO_$t", $p->get("BRCM_KERNEL_CRYPTO_$t") );
    }
    if ( $p->get("BRCM_KERNEL_CRYPTO_SHA2") ) {
        $c->set( "CONFIG_CRYPTO_SHA256", $p->get("BRCM_KERNEL_CRYPTO_SHA2") );
        $c->set( "CONFIG_CRYPTO_SHA512", $p->get("BRCM_KERNEL_CRYPTO_SHA2") );
    }
    $c->set( "CONFIG_CRYPTO_CBC", "y" );
    if ( $chip =~ /^(4908|63158|6858|47622)$/ ) {
       $c->set( "CONFIG_CRYPTO_ECB", "y" );
       $c->set( "CONFIG_CRYPTO_CTR", "y" );
       $c->set( "CONFIG_CRYPTO_GCM", "y" );
       $c->set( "CONFIG_CRYPTO_CCM", "y" );
       $c->set( "CONFIG_CRYPTO_XTS", "y" );
    }
}


if ( $p->get("BUILD_EBTABLES") ) {
    $c->set(
        [
            qw[
              CONFIG_BRIDGE_NF_EBTABLES CONFIG_BRIDGE_EBT_T_FILTER
              CONFIG_BRIDGE_EBT_T_NAT CONFIG_BRIDGE_EBT_BROUTE
              CONFIG_BRIDGE_EBT_IP CONFIG_BRIDGE_EBT_MARK
              CONFIG_BRIDGE_EBT_VLAN CONFIG_BRIDGE_EBT_TIME
              CONFIG_BRIDGE_EBT_SKBVLAN CONFIG_BRIDGE_EBT_BLOG
              CONFIG_BRIDGE_EBT_MARK_T CONFIG_BRIDGE_EBT_FTOS_T
              CONFIG_BRIDGE_EBT_SKIPLOG_T CONFIG_BRIDGE_EBT_QOS_MAP
              CONFIG_BRIDGE_EBT_U32 CONFIG_BRIDGE_EBT_REJECT]
        ],
        'y'
    );
    if ( $p->get("BRCM_DRIVER_WIRELESS") ) {
        $c->set( "CONFIG_BRIDGE_EBT_WMM_MARK", 'y' );
    }
}

if ( $p->get("BUILD_MCAST_PROXY") || $p->get("BUILD_MCAST_SNOOP") ) {

      $c->set( "CONFIG_BCM_MCAST", 'm' );

   if ( $p->get("BUILD_MCAST_PROXY") ) {
       $c->set( "CONFIG_IP_MULTICAST", 'y' );
       if ( $p->get("BUILD_IPV6") ) {
           $c->set( "CONFIG_IPV6_PIMSM_V2", 'y' );
       }
   }

   if ( $p->get("BUILD_MCAST_SNOOP") ) {
       $c->set( "CONFIG_BR_IGMP_SNOOP", 'y' );
       $c->set( "CONFIG_IP_MROUTE",    'y' );
       if ( $p->get("BUILD_IPV6") ) {
           $c->set( "CONFIG_BR_MLD_SNOOP", 'y' );
           $c->set( "CONFIG_IPV6_MROUTE",   'y' );
       }
   }
}


if ( $p->get("BRCM_KERNEL_NETQOS") ) {
    $c->set(
        [
            qw[
              CONFIG_IFB CONFIG_NET_SCHED CONFIG_NET_SCH_CLK_JIFFIES
              CONFIG_NET_SCH_CBQ CONFIG_NET_SCH_HTB CONFIG_NET_SCH_PRIO
              CONFIG_NET_SCH_SFQ CONFIG_NET_SCH_TBF CONFIG_NET_SCH_DSMARK
              CONFIG_NET_SCH_LLQ
              CONFIG_NET_SCH_INGRESS CONFIG_NET_QOS CONFIG_NET_ESTIMATOR
              CONFIG_NET_CLS CONFIG_NET_CLS_TCINDEX CONFIG_NET_CLS_ROUTE4
              CONFIG_NET_CLS_FW CONFIG_NET_CLS_IND
              CONFIG_NET_CLS_U32 CONFIG_NET_CLS_ACT CONFIG_NET_ACT_POLICE
              CONFIG_NET_ACT_GACT CONFIG_NET_ACT_MIRRED
              ]

              #CONFIG_NET_CLS_ROUTE
        ],
        'y'
    );
}

if ( $p->get("BUILD_VCONFIG") || $p->get("BUILD_WANVLANMUX") ) {
    $c->set( "CONFIG_VLAN_8021Q", 'y' );
}

$c->set( "CONFIG_VXLAN", 'y' );

if ( $p->get("BUILD_IPV6") ) {
    $c->set(
        [
            qw[
              CONFIG_IPV6 CONFIG_IPV6_TUNNEL
              CONFIG_IPV6_MULTIPLE_TABLES CONFIG_IPV6_SIT
              CONFIG_IPV6_SIT_6RD CONFIG_IPV6_ROUTER_PREF
              ]

              # CONFIG_INET6_TUNNEL  is not in template
        ],
        'y'
    );
    $c->set(
        [
            qw[
              CONFIG_IP6_NF_IPTABLES CONFIG_IP6_NF_FILTER
              CONFIG_IP6_NF_MANGLE CONFIG_IP6_NF_RAW
              CONFIG_IP6_NF_QUEUE CONFIG_IP6_NF_TARGET_LOG
              CONFIG_IP6_NF_NAT CONFIG_IP6_NF_TARGET_NPT CONFIG_IP_NF_TARGET_NETMAP
              CONFIG_NF_CONNTRACK_IPV6
              ]
        ],
        'm'
    );
    if ( $p->get("BRCM_KERNEL_CRYPTO") ) {
        $c->set(
            [
                qw[
                  CONFIG_INET6_AH CONFIG_INET6_ESP
                  CONFIG_INET6_XFRM_MODE_TRANSPORT
                  CONFIG_INET6_XFRM_MODE_TUNNEL]
            ],
            'y'
        );
    }
    if ( $p->get("BUILD_EBTABLES") ) {
        $c->set( "CONFIG_BRIDGE_EBT_IP6", 'y' );
    }

    if ( $p->get("BUILD_MAP") ) {
        $c->set( "CONFIG_BRCM_MAP", 'y' );
        $c->driver_setup( "MAP", "MAP" );
    }
}


if ( $p->get("BUILD_IPROUTE2") ) {
    $c->set(
        [
            qw[CONFIG_IP_ADVANCED_ROUTER CONFIG_ASK_IP_FIB_HASH
              CONFIG_IP_MULTIPLE_TABLES CONFIG_IP_ROUTE_FWMARK]
        ],
        'y'
    );
}


if ( $p->get("BUILD_IPSEC_TOOLS") ) {

    # to emulate gendefconfig's logic,
    # make sure that "CONFIG_XFRM_USER" isn't already "y"
    $c->set( "CONFIG_XFRM_USER", 'm' ) unless $c->get("CONFIG_XFRM_USER");
    $c->set(
        [
            qw[
              CONFIG_XFRM CONFIG_XFRM_MIGRATE CONFIG_NET_KEY
              CONFIG_NET_KEY_MIGRATE
              ]
        ],
        'y'
    );
}

if ( $p->get("BUILD_OPENVPN") ) {
    $c->set( "CONFIG_TUN", 'y' )
}

$c->set( "CONFIG_L2TP", $p->get("BUILD_L2TPAC") );
$c->set( "CONFIG_PPPOL2TP", $p->get("BUILD_L2TPAC") );
$c->set( "CONFIG_PPTP", $p->get("BUILD_ACCEL_PPTP") );
$c->set( "CONFIG_ACCEL_PPTP", $p->get("BUILD_ACCEL_PPTP") );

if ( !$p->get("ENABLE_PRINTK_AND_BUG") ) {
#    $c->unset("CONFIG_PRINTK");
    $c->unset("CONFIG_BUG");
}

if ( my $i = $p->get("BCM_DEFAULT_CONSOLE_LOGLEVEL") ) {
    $c->set( "CONFIG_BCM_DEFAULT_CONSOLE_LOGLEVEL", $i );
}

$c->set( "CONFIG_PRINTK_TIME", $p->get("BCM_PRINTK_TIME") );

if ( my $i = $p->get("BRCM_MAX_BSD_PTP") ) {
    $c->set( "CONFIG_LEGACY_PTY_COUNT", $i );
}


if ( !$p->get("BCM_IUDMA_RX_SPLITTING") || ( $chip =~ /^(63268)$/ ) ) {
    $c->unset("CONFIG_BCM_PKTDMA_RX_SPLITTING");
}
if ( !$p->get("BCM_IUDMA_TX_SPLITTING") || ( $chip =~ /^(63268)$/ ) ) {
    $c->unset("CONFIG_BCM_PKTDMA_TX_SPLITTING");
}


foreach my $i (qw[OFF 16M 32M 64M]) {
    $c->set(
        "CONFIG_BRCM_MEMORY_RESTRICTION_$i",
        $p->get("BRCM_MEMORY_RESTRICTION_$i")
    );
}

$c->set( "CONFIG_BRCM_OLT_FPGA_RESTORE", $p->get("BUILD_GPONOLT_TEST_UTILS") );


if ( $p->get('BUILD_ATMWAN') ) {
    $c->set( 'CONFIG_ATM',                                   'y' );
}


if ( $p->get("BUILD_PPPD") ) {
    $c->set(
        [
            qw[CONFIG_PPP CONFIG_PPP_FILTER CONFIG_PPP_ASYNC CONFIG_PPP_SYNC_TTY
              CONFIG_PPP_DEFLATE CONFIG_PPP_BSDCOMP CONFIG_PPPOE CONFIG_SLHC]
        ],
        'y'
    );
}


if ( $p->get("BUILD_RDPA") ) {
    $c->set( "CONFIG_BCM_BDMF", $p->get("BRCM_DRIVER_BDMF") );
    $c->set( "CONFIG_BCM_RDPA", $p->get("BRCM_DRIVER_RDPA") );
    $c->set( "CONFIG_BCM_RDPA_GPL", $p->get("BRCM_DRIVER_RDPA_GPL") );
    $c->set( "CONFIG_BCM_RDPA_USR", $p->get("BRCM_DRIVER_RDPA_USR") );
    $c->driver_setup( "RDPA_GPL_EXT", "RDPA_GPL_EXT" );
    $c->driver_setup( "RDPA_MW", "RDPA_MW" );
    $c->driver_setup( "RDPA_DRV", "RDPA_DRV" );
    $c->set( "CONFIG_BCM_RUNNER_MAX_FLOWS", $p->get("BRCM_RUNNER_MAX_FLOWS") );
    if ( $chip =~ /^(63138|63148|4908|63158)$/ ) {
        if ( $p->get("BRCM_RDPA_MCAST_SUPPORT") eq "y") {
            $c->set( "CONFIG_BCM_RDPA_MCAST", "y" );
        }
    }
    if ( $chip =~ /^(4908)$/ ) {
        $c->driver_setup( "FPM", "FPM" );
        $c->set( "CONFIG_BCM_FPM_POOL_NUM", $p->get("BRCM_FPM_POOL_NUM") );
        if ( $p->get("BRCM_FPM_USE_DT") ) {
            $c->set( "CONFIG_BCM_FPM_DT", "y" );
        }
    }
}

if ( $chip =~ /^(6838|6848|6858|63158|6846|6856|6878|6855)$/ ) {
    $c->driver_setup( "GPON_STACK", "GPON_STACK" );
    if ( ! ( $chip =~ /^(63158)$/ ) ) {
        $c->driver_setup( "RDPA_BRIDGE", "RDPA_BRIDGE" );
    }
    $c->driver_setup( "GPON", "GPON" );
    if ( my $i = $p->get("GPON_ONU_TYPE") ) {
        $c->set( "CONFIG_$i", "y" );
    }
    if ( $p->get("BUILD_NGPON") ) {
        $c->set( 'CONFIG_BCM_NGPON', 'm' );
    }
}

$c->set( "CONFIG_BRCM_MINIGW", $p->get("BRCM_MINIGW") );

$c->driver_setup( "PCI", "PCI" );
if ( $p->get("BRCM_DRIVER_PCI") ) {
    if ( my $i = $p->get("BRCM_DRIVER_PCI_MSI") ) {
        $c->set( "CONFIG_PCI_MSI", $i );
    }
#default PCIE_HCD=m and IMPL=1
    if ( $chip =~ /^(60333|63268|63381|6838|6848|47189)$/ ) {
        $c->set( "CONFIG_BCM_PCIE_HCD", "y" );
    }
    if ( $chip =~ /^(47189)$/ ) {
       $c->setup_impl("PCIE_HCD");
    }
}

if ( $chip =~ /^(6838|6848|63138|63148|63268|6858|4908|63158|6846|6856|63381|47189|6878|6855)$/ ) {
    $c->driver_setup( "WIFI_FORWARDING_DRV", "WIFI_FORWARDING_DRV" );
}

#Archer platforms without pktfwd or archer wireless
if ( ( $chip =~ /^(63178|47622)$/ ) && ( ( !$p->get("BUILD_BCM_PKTFWD") || !$p->get("BRCM_DRIVER_ARCHER_WLAN") ) ) ) {
    $c->driver_setup( "WIFI_FORWARDING_DRV", "WIFI_FORWARDING_DRV" );
}

if ( $chip =~ /^(6838|6848|6846|6856|6858|6878)$/ ) {
    $c->set( "CONFIG_BCM_WFD_RATE_LIMITER", "y" );
}

if ( $chip =~ /^(6858)$/ ) {
    $c->driver_setup( "NETXL", "NETXL" );
}

if ( $chip =~ /^(6838|6848|63148|63138|4908|6858|63158|6856|6846|6878)$/ ) {
    $c->driver_setup( "DHD_RUNNER", "DHD_RUNNER" );
}

if ( $chip =~ /^(6838|6848|63148|63138|63381|6848|6858|4908|63158|6846|6856|47622|63178|6878|6855)$/ ) {
    $c->driver_setup( "PMC", "PMC" );
}

if ( $chip =~ /^(6838|6848|63148|63138|63381|6858|4908|63158|6846|6856|47622|63178|6878|6855)$/ ) {
    $c->driver_setup( "EXT_TIMER", "EXT_TIMER" );
    $c->set( "CONFIG_TIMERFD", "y");    
    if ( $p->get("BRCM_DRIVER_TIMER") ) {
        $c->set( "CONFIG_BCM_TIMER",  "y" );
    }
}

$c->driver_setup( "WATCHDOG_TIMER", "WATCHDOG_TIMER" );

if ( $chip =~ /^(6838|6848|6858|6846|6856|6878|6855)$/ ) {
    $c->driver_setup( "SIM_CARD", "SIM_CARD" );
    $c->driver_setup( "PMD", "PMD" );
}

if ( $chip =~ /^(63158)$/ ) {
    $c->driver_setup( "PMD", "PMD" );
}

if ( $chip =~ /^(63138|63148|4908|6858|63158|6846|6856|6878|6855)$/ ) {
        $c->driver_setup( "UBUSCAP", "UBUSCAP" );
}

if ( $chip =~ /^(4908|63158)$/ ) {
        $c->driver_setup( "MEMCCAP", "MEMCCAP" );
}

if ( $chip =~ /^(63138)$/ ) {
    if ( $p->get("BRCM_DRIVER_ACP") ) {
        $c->set( "CONFIG_PLAT_BCM63XX_ACP", "y" );
        $c->set( "CONFIG_BCM_ZONE_ACP", "y" );
        $c->set( 'CONFIG_BCM_ACP_MEM_SIZE', $p->get('BRCM_ACP_SIZE') );
    }
}


if ( $p->get('BUILD_ETHTOOL') ) {
    $c->set( 'CONFIG_EPOLL', 'y' );
    $c->set( 'CONFIG_BCM_ETHTOOL', 'y' );
}

if ( $p->get('BUILD_SWMDK') ) {
    $c->set( 'CONFIG_BCM_SWMDK', 'y' );
}

if ( $p->get('BRCM_SWITCH_SCHED_SP') ) {
    $c->set( 'CONFIG_BCM_SWITCH_SCHED_SP', 'y' );
}

if ( $p->get('BRCM_SWITCH_SCHED_WRR') ) {
    $c->set( 'CONFIG_BCM_SWITCH_SCHED_WRR', 'y' );
}

# Time Synchronization
if ( $chip =~ /^(6838|6848|6858|6846|6856|63158|6878|6855)$/ ) {

    # Driver
    $c->driver_setup( "TIME_SYNC", "TIME_SYNC" );

    # GPON ToDD
    if ( $p->get( "BRCM_GPON_TODD" ) ) {
        $c->set( "CONFIG_BCM_GPON_TODD", "y" );
        $c->set( "CONFIG_BCM_TIME_SYNC_1PPS", "y" );
    }

    # PTP 1588
    if ( $p->get( "BRCM_PTP_1588" ) ) {
        $c->set( "CONFIG_BCM_PTP_1588", "y" );
    }
    
    # Sync Clock: 8KHz
    if ( $p->get( "BRCM_TIME_SYNC_8KHZ" ) ) {
        $c->set( "CONFIG_BCM_TIME_SYNC_8KHZ", "y" );
    }

    # Sync Signal: PON Unstable
    if ( $p->get( "BRCM_TIME_SYNC_PON_UNSTABLE" ) ) {
        $c->set( "CONFIG_BCM_TIME_SYNC_PON_UNSTABLE", "y" );
    }
}

# Presecure / Fullsecure targets in which OTP fusing is down from Linux
if ( $p->get("BRCM_DRIVER_OTP") ) {
    $c->driver_setup( "OTP", "OTP" );
}

# SOTP read write from Linux
if ( $p->get("BRCM_DRIVER_SOTP") ) {
    $c->driver_setup( "SOTP", "SOTP" );
}

# LXC Kernel Requirements
if ( $p->get( 'BUILD_LXC' ) || $p->get( 'BUILD_MODSW_DOCKEREE' ) ) {

    # Namespaces configs
    $c->set( "CONFIG_NAMESPACES",                       'y' );
    $c->set( "CONFIG_UTS_NS",                           'y' );
    $c->set( "CONFIG_IPC_NS",                           'y' );
    $c->set( "CONFIG_PID_NS",                           'y' );
    $c->set( "CONFIG_USER_NS",                          'y' );
    $c->set( "CONFIG_NET_NS",                           'y' );
    $c->set( "CONFIG_DEVPTS_MULTIPLE_INSTANCES",        'y' );

    # Cgroups configs
    $c->set( "CONFIG_CGROUPS",                          'y' );
    $c->set( "CONFIG_CGROUP_NS",                        'y' );
    $c->set( "CONFIG_CGROUP_DEVICE",                    'y' );
    $c->set( "CONFIG_CGROUP_SCHED",                     'y' );
    $c->set( "CONFIG_CGROUP_CPUACCT",                   'y' );
    $c->set( "CONFIG_MEMCG",                            'y' );
    $c->set( "CONFIG_MEMCG_SWAP",                       'y' );
    $c->set( "CONFIG_MEMCG_KMEM",                       'y' );
    $c->set( "CONFIG_CGROUP_MEM_RES_CTLR",              'y' );
    $c->set( "CONFIG_CGROUP_MEM_RES_CTLR_SWAP",         'y' );
    $c->set( "CONFIG_CGROUP_MEM_RES_CTLR_SWAP_ENABLED", 'y' );
    $c->set( "CONFIG_CGROUP_MEM_RES_CTLR_KMEM",         'y' );
    $c->set( "CONFIG_CPUSETS",                          'y' );
    $c->set( "CONFIG_CGROUP_FREEZER",                   'y' );
    $c->set( "CONFIG_FAIR_GROUP_SCHED",                 'y' );
    $c->set( "CONFIG_RT_GROUP_SCHED",                   'y' );
    $c->set( "CONFIG_BLK_CGROUP",                       'y' );
    $c->set( "CONFIG_IOSCHED_CFQ",                      'y' );
    $c->set( "CONFIG_CFQ_GROUP_IOSCHED",                'y' );
    $c->set( "CONFIG_CFS_BANDWIDTH",                    'y' );
    $c->unset( "CONFIG_DEBUG_BLK_CGROUP" );
    $c->set( "CONFIG_BLK_DEV_THROTTLING",               'y' );
    $c->set( "CONFIG_NETPRIO_CGROUP",                   'y' );

    # Misc configs
    $c->set( "CONFIG_VETH",                             'y' );
    $c->set( "CONFIG_MACVLAN",                          'y' );
    $c->set( "CONFIG_VLAN_8021Q",                       'y' );
    $c->unset( "CONFIG_MACVTAP" );
    $c->set( "CONFIG_RESOURCE_COUNTERS",                'y' );
    $c->set( "CONFIG_BRIDGE",                           'y' );
    $c->set( "CONFIG_EVENTFD",                          'y' );
    $c->set( "CONFIG_SIGNALFD",                         'y' );
    $c->set( "CONFIG_EPOLL",                            'y' );
}

#Seccomp kernel requirements
if ( $p->get('BUILD_LIBSECCOMP') ) {
    $c->set( 'CONFIG_OABI_COMPAT',              'n' );
    $c->set( 'CONFIG_SECCOMP',                  'y' );
    $c->set( 'CONFIG_SECCOMP_FILTER',           'y' );
    $c->set( 'CONFIG_HAVE_ARCH_SECCOMP_FILTER', 'y' );
}

#Docker kernel requirements
if ( $p->get('BUILD_MODSW_DOCKEREE') ) {
    $c->set( 'CONFIG_ADVISE_SYSCALLS', 'y' );
    $c->set( 'CONFIG_KEYS',            'y' );
    $c->set( 'CONFIG_POSIX_MQUEUE',    'y' );
}

#filesystem support
if ( $p->get("LINUX_KERNEL_USBMASS") || $p->get("BUILD_SATA") ) {

    $c->set(
            [
            qw[
            CONFIG_HOTPLUG
            CONFIG_SCSI CONFIG_SCSI_PROC_FS CONFIG_BLK_DEV_SD
            CONFIG_FAT_FS CONFIG_VFAT_FS CONFIG_FUSE_FS
            CONFIG_SYSFS CONFIG_RAMFS CONFIG_PARTITION_ADVANCED
            CONFIG_LDM_PARTITION CONFIG_MSDOS_PARTITION
            CONFIG_NLS CONFIG_NLS_CODEPAGE_437
            CONFIG_NLS_ISO8859_1 ]
            ],
            'y'
           );
    $c->set( "CONFIG_FAT_DEFAULT_CODEPAGE", "437" );

# the double-quotes are part of the value
    $c->set( "CONFIG_FAT_DEFAULT_IOCHARSET", q["iso8859-1"] );
    $c->set( "CONFIG_NLS_DEFAULT",           q["iso8859-1"] );
    $c->set( "CONFIG_EXT4_FS",  "y" );
    $c->set( "CONFIG_EXT4_USE_FOR_EXT23",  "y" );
    $c->set( "CONFIG_EXT4_FS_XATTR",  "y" );
    $c->set( "CONFIG_EXT4_FS_POSIX_ACL",  "y" );
    $c->set( "CONFIG_EXT4_FS_SECURITY",  "y" );
    $c->set( "CONFIG_EXT4_DEBUG",  "n" );
    $c->set( "CONFIG_JBD2_DEBUG",  "n" );
}

if ( $p->get("BUILD_OPENVSWITCH") ) {
    $c->set( "CONFIG_EVENTFD", "y");
    $c->set( "CONFIG_SIGNALFD", "y" );
    $c->set( "CONFIG_EPOLL", "y" );
    $c->set( "CONFIG_LIBCRC32C", "y" );
    $c->set( "CONFIG_NET_IPGRE_DEMUX", "m" );
}

if ( $p->get("BUILD_BCM_ASOC_AUDIO") ) {
    $c->set( "CONFIG_SOUND", "y");
    $c->set( "CONFIG_SND", "y");
    $c->set( "CONFIG_SND_SOC", "y");
    $c->set("CONFIG_SND_TIMER",                 "y");
    $c->set("CONFIG_SND_PCM",                   "y");
    $c->set("CONFIG_SND_HWDEP" ,                "y");
    $c->set("CONFIG_SND_RAWMIDI",               "y");
    $c->set("CONFIG_SND_DYNAMIC_MINORS",        "y");
    $c->set("CONFIG_SND_MAX_CARDS",             "y");

    $c->set( "CONFIG_BCM_SOUND", "y");

    if ( $p->get("SND_SOC_CS4345") ) {
      $c->set( "CONFIG_SND_SOC_CS4345", "y");
    }
    if ( $p->get("SND_SOC_PCM5100") ) {
      $c->set( "CONFIG_SND_SOC_PCM5100", "y");
    } 
    if ( $p->get("SND_SOC_MAPLELEAF") ) {
      $c->set( "CONFIG_SND_SOC_MAPLELEAF", "y");
      if( $chip =~ /^(63178)$/ ){ # i2c bit banging
          $c->set( "CONFIG_I2C",                  "y" );
          $c->set( "CONFIG_I2C_CHARDEV",          "y" );
          $c->set( 'CONFIG_ARCH_REQUIRE_GPIOLIB', "y" );
          $c->set( "CONFIG_GPIOLIB",              "y" );
          $c->set( "CONFIG_I2C_GPIO",             "y" );
          $c->set( "CONFIG_GPIO_SYSFS",           "y" );
          $c->set( "CONFIG_OF_GPIO",              "y" );
          $c->set( "CONFIG_GPIO_DEVRES",          "y" );
          $c->set( "CONFIG_GPIO_GENERIC_PLATFORM","y" );
      }
    }

    if ( $chip =~ /^(63158|63178|47622|6856)$/ ) {
      $c->set( "CONFIG_BCM_COMMON_CLK_I2S", "y");
    }

    if ( $chip =~ /^(63178|47622)$/ ) {
      $c->set( "CONFIG_SND_BCM63xx_I2S_WHISTLER", "y");
    }
    if ( $chip =~ /^(63158)$/ ) {
      if ($chip_rev eq "A0") {
        $c->set( "CONFIG_SND_BCM63xx_SOC_I2S_ENG", "y");
      }
      else{
        $c->set( "CONFIG_SND_BCM63xx_I2S_WHISTLER", "y");
      }
    }

    if ( $chip =~ /^(63138|63148)$/ ){
      $c->set( "CONFIG_SND_BCM63148_SOC_I2S", "y");
    }
    if ( $chip =~ /^(6856)$/ ) {
      $c->set( "CONFIG_SND_BCM6856_SOC_I2S", "y");
    }
    if ( $chip =~ /^(63158|63178|47622)$/ ) {
      $c->set( "CONFIG_SND_BCM63XX_SOC_I2S_MACH", "y");
    }
}

if ( $p->get("BRCM_REASON_TO_SKB_MARK") ) {
      $c->set( "CONFIG_BCM_REASON_TO_SKB_MARK", "y");
}

if ( $p->get("BRCM_DW_CXC_DATA_MODE") ) {
      $c->set( "CONFIG_BCM_DW_CXC_DATA_MODE", "y");
}

if ( $p->get("BRCM_RNR_CPU_RX_DYN_METER") ) {
      $c->set( "CONFIG_BCM_RNR_CPU_RX_DYN_METER", "y");
}

if ( $p->get("BCM_FCACHE_CLASSIFICATION_BYPASS") ) {
      $c->set( "CONFIG_BCM_FCACHE_CLASSIFICATION_BYPASS", "y");
}

if ( $p->get("BUILD_BCM_DSP_ALSA_BRIDGE") ) {
    $c->set( "CONFIG_BCM_DSP_ALSA_BRIDGE", "y");
}

if ( $p->get("BCM_WLAN_16BIT_STATION_CHAIN_IDX_SUPPORT") ) {
    $c->set( "CONFIG_BCM_WLAN_16BIT_STATION_CHAIN_IDX_SUPPORT",  "y" );
}

if ( $p->get("BUILD_BCM_PKTFWD") ) {
    if ( ($p->get("BUILD_BRCM_HNDROUTER") || ($p->get("BUILD_BRCM_CPEROUTER"))) ) {
        $c->set( "CONFIG_BCM_PKTFWD", "y" );
        if ( $p->get("BUILD_BCM_PKTFWD_FLCTL") ) {
            $c->set( "CONFIG_BCM_PKTFWD_FLCTL", "y" );
        }
    }
}
else {
    if ( ( $chip =~ /^(63178|47622|47189)$/ ) && ( $p->get("BUILD_BCM_CPEPKTC") ) ) {
        $c->set( "CONFIG_BCM_CPEPKTC", "y" );
    }
}

if ( $p->get("BUILD_BCM_WLAN_REMOVE_INTERNAL_DEBUG") ) {
    $c->set( "CONFIG_BCM_WLAN_REMOVE_INTERNAL_DEBUG", "y" );
}

if ( $chip =~ /^(6858|4908|47622)$/ ) {
	$c->driver_setup( "EAPFWD", "EAPFWD" );
}

if ( $p->get("BUILD_BSTREAM_IQOS") ) {
    $c->set( "CONFIG_CLS_U32_MARK", "y");
    $c->set( "CONFIG_NF_CONNTRACK_MARK", "y");
    $c->set( "CONFIG_NF_CONNTRACK_EVENTS", "y");
}


if ( $p->get("BUILD_BCM_CLEDS_PROC_DRIVER") ) {
    $c->set( "CONFIG_BCM_CLEDS_PROC_DRIVER", 'y' );
}

if ( $p->get("BCM_WLCLED") ) {
    $c->set( "CONFIG_BCM_WLCLED", 'y' );
}

if ( $p->get('BUILD_IMAGE_OFFSET_ZERO') ) {
    $c->set( 'CONFIG_BCM_IMAGE_OFFSET_ZERO', 'y' );
}

# LAST LINE: ADD ABOVE!
$c->write( );

