From ddab08350235a702efc5246c48131e6b8fea031c Mon Sep 17 00:00:00 2001
From: Arun LK <Arun_L_K@dell.com>
Date: Tue, 21 Sep 2021 18:00:04 +0530
Subject: [PATCH 1/2] DellEMC: N3248TE Initial platform commit

---
 .../DellEMC-N3248TE/buffers.json.j2           |    2 +
 .../DellEMC-N3248TE/buffers_defaults_t0.j2    |   41 +
 .../DellEMC-N3248TE/buffers_defaults_t1.j2    |   41 +
 .../copp_capabilities_config.j2               |    3 +
 .../DellEMC-N3248TE/copp_platform_config.j2   |  145 ++
 .../DellEMC-N3248TE/custom_led.bin            |  Bin 0 -> 606 bytes
 .../hx5-n3248te-48x1G+4x10G.config.bcm        |  260 ++++
 .../DellEMC-N3248TE/linkscan_led_fw.bin       |  Bin 0 -> 6100 bytes
 .../DellEMC-N3248TE/pg_profile_lookup.ini     |   17 +
 .../DellEMC-N3248TE/port_config.ini           |   55 +
 .../DellEMC-N3248TE/qos.json.j2               |    1 +
 .../DellEMC-N3248TE/qos_config_t1.j2          |  175 +++
 .../DellEMC-N3248TE/sai.profile               |    1 +
 .../DellEMC-N3248TE/sai_preinit_cmd.soc       |    2 +
 .../default_sku                               |    1 +
 .../init_cfg.json                             |   13 +
 .../installer.conf                            |    3 +
 .../led_proc_init.soc                         |    7 +
 .../plugins/eeprom.py                         |   22 +
 .../plugins/fanutil.py                        |   73 +
 .../plugins/pcie.yaml                         |   16 +
 .../plugins/psuutil.py                        |  191 +++
 .../plugins/sfputil.py                        |  176 +++
 .../pmon_daemon_control.json                  |    3 +
 .../sensors.conf                              |   58 +
 platform/broadcom/one-image.mk                |    1 +
 platform/broadcom/platform-modules-dell.mk    |    6 +
 .../debian/control                            |    5 +
 .../debian/platform-modules-n3248te.init      |   39 +
 .../debian/platform-modules-n3248te.install   |   12 +
 .../debian/platform-modules-n3248te.postinst  |    7 +
 .../sonic-platform-modules-dell/debian/rules  |   12 +-
 .../n3248te/cfg/n3248te-modules.conf          |   14 +
 .../n3248te/modules/Makefile                  |    2 +
 .../n3248te/modules/dell_n3248te_platform.c   | 1236 +++++++++++++++++
 .../n3248te/modules/emc2305.c                 |  877 ++++++++++++
 .../n3248te/modules/pmbus.h                   |  425 ++++++
 .../n3248te/scripts/fancontrol.sh             |   78 ++
 .../n3248te/scripts/n3248te_platform.sh       |  143 ++
 .../n3248te/scripts/platform_sensors.py       |  139 ++
 .../n3248te/scripts/portiocfg.py              |  106 ++
 .../n3248te/scripts/ports_xcvrd_notify.py     |  113 ++
 .../n3248te/scripts/sensors                   |    8 +
 .../n3248te/setup.py                          |    1 +
 .../n3248te/sonic_platform/__init__.py        |    8 +
 .../n3248te/sonic_platform/chassis.py         |  351 +++++
 .../n3248te/sonic_platform/component.py       |   84 ++
 .../n3248te/sonic_platform/eeprom.py          |  134 ++
 .../n3248te/sonic_platform/fan.py             |  169 +++
 .../n3248te/sonic_platform/fan_drawer.py      |   37 +
 .../n3248te/sonic_platform/platform.py        |   24 +
 .../n3248te/sonic_platform/psu.py             |  204 +++
 .../n3248te/sonic_platform/sfp.py             |  787 +++++++++++
 .../n3248te/sonic_platform/thermal.py         |  145 ++
 .../n3248te/sonic_platform/watchdog.py        |  214 +++
 .../systemd/platform-modules-n3248te.service  |   14 +
 src/sonic-device-data/tests/permitted_list    |    4 +
 57 files changed, 6704 insertions(+), 1 deletion(-)
 create mode 100644 device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/buffers.json.j2
 create mode 100644 device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/buffers_defaults_t0.j2
 create mode 100644 device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/buffers_defaults_t1.j2
 create mode 100644 device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/copp_capabilities_config.j2
 create mode 100644 device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/copp_platform_config.j2
 create mode 100644 device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/custom_led.bin
 create mode 100644 device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/hx5-n3248te-48x1G+4x10G.config.bcm
 create mode 100644 device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/linkscan_led_fw.bin
 create mode 100644 device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/pg_profile_lookup.ini
 create mode 100644 device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/port_config.ini
 create mode 100644 device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/qos.json.j2
 create mode 100644 device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/qos_config_t1.j2
 create mode 100644 device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/sai.profile
 create mode 100644 device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/sai_preinit_cmd.soc
 create mode 100644 device/dell/x86_64-dellemc_n3248te_c3338-r0/default_sku
 create mode 100644 device/dell/x86_64-dellemc_n3248te_c3338-r0/init_cfg.json
 create mode 100644 device/dell/x86_64-dellemc_n3248te_c3338-r0/installer.conf
 create mode 100644 device/dell/x86_64-dellemc_n3248te_c3338-r0/led_proc_init.soc
 create mode 100644 device/dell/x86_64-dellemc_n3248te_c3338-r0/plugins/eeprom.py
 create mode 100644 device/dell/x86_64-dellemc_n3248te_c3338-r0/plugins/fanutil.py
 create mode 100644 device/dell/x86_64-dellemc_n3248te_c3338-r0/plugins/pcie.yaml
 create mode 100644 device/dell/x86_64-dellemc_n3248te_c3338-r0/plugins/psuutil.py
 create mode 100644 device/dell/x86_64-dellemc_n3248te_c3338-r0/plugins/sfputil.py
 create mode 100644 device/dell/x86_64-dellemc_n3248te_c3338-r0/pmon_daemon_control.json
 create mode 100644 device/dell/x86_64-dellemc_n3248te_c3338-r0/sensors.conf
 create mode 100755 platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-n3248te.init
 create mode 100644 platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-n3248te.install
 create mode 100644 platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-n3248te.postinst
 create mode 100644 platform/broadcom/sonic-platform-modules-dell/n3248te/cfg/n3248te-modules.conf
 create mode 100644 platform/broadcom/sonic-platform-modules-dell/n3248te/modules/Makefile
 create mode 100644 platform/broadcom/sonic-platform-modules-dell/n3248te/modules/dell_n3248te_platform.c
 create mode 100644 platform/broadcom/sonic-platform-modules-dell/n3248te/modules/emc2305.c
 create mode 100644 platform/broadcom/sonic-platform-modules-dell/n3248te/modules/pmbus.h
 create mode 100755 platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/fancontrol.sh
 create mode 100755 platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/n3248te_platform.sh
 create mode 100755 platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/platform_sensors.py
 create mode 100755 platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/portiocfg.py
 create mode 100755 platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/ports_xcvrd_notify.py
 create mode 100755 platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/sensors
 create mode 120000 platform/broadcom/sonic-platform-modules-dell/n3248te/setup.py
 create mode 100644 platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/__init__.py
 create mode 100644 platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/chassis.py
 create mode 100644 platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/component.py
 create mode 100644 platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/eeprom.py
 create mode 100644 platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/fan.py
 create mode 100644 platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/fan_drawer.py
 create mode 100644 platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/platform.py
 create mode 100644 platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/psu.py
 create mode 100644 platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/sfp.py
 create mode 100644 platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/thermal.py
 create mode 100644 platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/watchdog.py
 create mode 100644 platform/broadcom/sonic-platform-modules-dell/n3248te/systemd/platform-modules-n3248te.service

diff --git a/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/buffers.json.j2 b/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/buffers.json.j2
new file mode 100644
index 000000000000..1083a6210fc9
--- /dev/null
+++ b/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/buffers.json.j2
@@ -0,0 +1,2 @@
+{%- set default_topo = 't0' %}
+{%- include 'buffers_config.j2' %}
diff --git a/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/buffers_defaults_t0.j2
new file mode 100644
index 000000000000..bfd81d10049f
--- /dev/null
+++ b/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/buffers_defaults_t0.j2
@@ -0,0 +1,41 @@
+{%- set default_cable = '5m' %}
+
+{%- macro generate_port_lists(PORT_ALL) %}
+    {# Generate list of ports #}
+    {% for port_idx in range(0,32) %}
+        {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %}
+    {% endfor %}
+{%- endmacro %}
+
+{%- macro generate_buffer_pool_and_profiles() %}
+    "BUFFER_POOL": {
+        "ingress_lossless_pool": {
+            "size": "8192000",
+            "type": "ingress",
+            "mode": "dynamic",
+            "xoff": "196608"
+        },
+        "egress_lossless_pool": {
+            "size": "8388608",
+            "type": "egress",
+            "mode": "static"
+        }
+    },
+    "BUFFER_PROFILE": {
+        "ingress_lossy_profile": {
+            "pool":"[BUFFER_POOL|ingress_lossless_pool]",
+            "size":"0",
+            "dynamic_th":"3"
+        },
+        "egress_lossless_profile": {
+            "pool":"[BUFFER_POOL|egress_lossless_pool]",
+            "size":"0",
+            "static_th":"8388608"
+        },
+        "egress_lossy_profile": {
+            "pool":"[BUFFER_POOL|egress_lossless_pool]",
+            "size":"1518",
+            "dynamic_th":"3"
+        }
+    },
+{%- endmacro %}
diff --git a/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/buffers_defaults_t1.j2
new file mode 100644
index 000000000000..3b9cd1f104d6
--- /dev/null
+++ b/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/buffers_defaults_t1.j2
@@ -0,0 +1,41 @@
+{%- set default_cable = '300m' %}
+
+{%- macro generate_port_lists(PORT_ALL) %}
+    {# Generate list of ports #}
+    {% for port_idx in range(0,32) %}
+        {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %}
+    {% endfor %}
+{%- endmacro %}
+
+{%- macro generate_buffer_pool_and_profiles() %}
+    "BUFFER_POOL": {
+        "ingress_lossless_pool": {
+            "size": "8192000",
+            "type": "ingress",
+            "mode": "dynamic",
+            "xoff": "196608"
+        },
+        "egress_lossless_pool": {
+            "size": "8388608",
+            "type": "egress",
+            "mode": "static"
+        }
+    },
+    "BUFFER_PROFILE": {
+        "ingress_lossy_profile": {
+            "pool":"[BUFFER_POOL|ingress_lossless_pool]",
+            "size":"0",
+            "dynamic_th":"3"
+        },
+        "egress_lossless_profile": {
+            "pool":"[BUFFER_POOL|egress_lossless_pool]",
+            "size":"0",
+            "static_th":"8388608"
+        },
+        "egress_lossy_profile": {
+            "pool":"[BUFFER_POOL|egress_lossless_pool]",
+            "size":"1518",
+            "dynamic_th":"3"
+        }
+    },
+{%- endmacro %}
diff --git a/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/copp_capabilities_config.j2 b/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/copp_capabilities_config.j2
new file mode 100644
index 000000000000..ba28f2410393
--- /dev/null
+++ b/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/copp_capabilities_config.j2
@@ -0,0 +1,3 @@
+{
+    "copp_rx_rate":15000
+}
diff --git a/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/copp_platform_config.j2 b/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/copp_platform_config.j2
new file mode 100644
index 000000000000..35c0066dc59e
--- /dev/null
+++ b/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/copp_platform_config.j2
@@ -0,0 +1,145 @@
+{
+    "COPP_GROUP": {
+        "copp-system-lacp": {
+            "cir":"250",
+            "cbs":"250"
+        },
+        "copp-system-udld": {
+            "cir":"250",
+            "cbs":"250"
+        },
+        "copp-system-stp": {
+            "cir":"8000",
+            "cbs":"8000"
+        },
+        "copp-system-bfd": {
+            "cir":"750",
+            "cbs":"750"
+        },
+        "copp-system-lldp": {
+            "cir":"250",
+            "cbs":"250"
+        },
+        "copp-system-vrrp": {
+            "cir":"250",
+            "cbs":"250"
+        },
+        "copp-system-iccp": {
+            "cir":"2500",
+            "cbs":"2500"
+        },
+        "copp-system-ospf": {
+            "cir":"2500",
+            "cbs":"2500"
+        },
+        "copp-system-bgp": {
+            "cir":"5000",
+            "cbs":"5000"
+        },
+        "copp-system-pim": {
+            "cir":"2500",
+            "cbs":"2500"
+        },
+        "copp-system-igmp": {
+            "cir":"1000",
+            "cbs":"1000"
+        },
+        "copp-system-suppress": {
+            "cir":"1500",
+            "cbs":"1500"
+        },
+        "copp-system-arp": {
+            "cir":"1500",
+            "cbs":"1500"
+        },
+        "copp-system-dhcp": {
+            "cir":"150",
+            "cbs":"150"
+        },
+        "copp-system-icmp": {
+            "cir":"500",
+            "cbs":"500"
+        },
+        "copp-system-ip2me": {
+            "cir":"3000",
+            "cbs":"3000"
+        },
+        "copp-system-subnet": {
+            "cir":"1000",
+            "cbs":"1000"
+        },
+        "copp-system-mtu": {
+            "cir":"250",
+            "cbs":"250"
+        },
+        "copp-system-sflow": {
+            "cir":"4000",
+            "cbs":"4000"
+        }
+    },
+    "SCHEDULER": {
+        "copp-scheduler-policy@23": {
+            "pir": "250"
+        },
+        "copp-scheduler-policy@22": {
+            "pir": "250"
+        },
+        "copp-scheduler-policy@21": {
+            "pir": "8000"
+        },
+        "copp-scheduler-policy@20": {
+            "pir": "750"
+        },
+        "copp-scheduler-policy@19": {
+            "pir": "2500"
+        },
+        "copp-scheduler-policy@18": {
+            "pir": "250"
+        },
+        "copp-scheduler-policy@17": {
+            "pir": "250"
+        },
+        "copp-scheduler-policy@16": {
+            "pir": "2500"
+        },
+        "copp-scheduler-policy@15": {
+            "pir": "2500"
+        },
+        "copp-scheduler-policy@14": {
+            "pir": "5000"
+        },
+        "copp-scheduler-policy@13": {
+            "pir": "2500"
+        },
+        "copp-scheduler-policy@12": {
+            "pir": "1000"
+        },
+        "copp-scheduler-policy@11": {
+            "pir": "1500"
+        },
+        "copp-scheduler-policy@10": {
+            "pir": "1500"
+        },
+        "copp-scheduler-policy@9": {
+            "pir": "150"
+        },
+        "copp-scheduler-policy@8": {
+            "pir": "500"
+        },
+        "copp-scheduler-policy@7": {
+            "pir": "3000"
+        },
+        "copp-scheduler-policy@6": {
+            "pir": "1000"
+        },
+        "copp-scheduler-policy@4": {
+            "pir": "250"
+        },
+        "copp-scheduler-policy@3": {
+            "pir": "4000"
+        },
+        "copp-scheduler-policy@1": {
+            "pir": "100"
+        }
+    }
+}
diff --git a/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/custom_led.bin b/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/custom_led.bin
new file mode 100644
index 0000000000000000000000000000000000000000..631b4712fa28c7bfb63dc04864b96e88166f1939
GIT binary patch
literal 606
zcmW-cy>C)s6vm(TUJ#Jd+9I~dEiJqSELU2~hiK6X7kU~(8WTx0K%=E5=B6_PBZkCi
zyZEtybTZw#)J8jLV&dp>S#|MGVAjQhXFkvK`#q!2Pv{|SQ;9~Ox~CHw-XQ#_+=;2O
zM~c+)$0X!?@@TEh;aub8<KQ`LX1alB%$TuWm>;Q961hNI)rIAZ;<qhYBx%^KrvzQG
zsuV1qpPg_{<OV32!K#wnjsF}XytcGa=}|`>k;?5t_L+sgJHJJ(ta#_u_EH7<QLhDG
z!ESCh5PC){hR=F#9#Z2!&(1t0#Jo_Ibi-ze0mcT>U#u`6!?JVS@wYzaZkn~KNFSdm
zNoRaGL}c-PCpxD2^KPwX)Cv{jh;mvh)hAusPyMM^g98Y&R)?H4JXY82kx>%s-nJ{Z
zW9$^9CQ=6uVeOGOAJ_JiWjd&f^|u(HU{)U}8E4|xP{{AQkZLn4i%pyCHr3NRUtUw6
zKF|q`zJ8<jZSV;wP+@}|7vO*sE?k5g6YyXXQ@Dg_%)pDw@Zkz(F$X`cA^;8Z2x0+?
z2q6rKB}5QK4A-!XICNY`0xMX>4dihT8@P*2Y@v+G7>QfR;wCakBZVZ^_-mEF6P(gH
zz055!Zi{fM<n|C#7MM2A)Bw}{Y%$9=KDP3*-85THv8{)#-E8mT6%Jlw=T$1N6Zi+E
C!g^)^

literal 0
HcmV?d00001

diff --git a/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/hx5-n3248te-48x1G+4x10G.config.bcm b/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/hx5-n3248te-48x1G+4x10G.config.bcm
new file mode 100644
index 000000000000..69536e86e7a4
--- /dev/null
+++ b/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/hx5-n3248te-48x1G+4x10G.config.bcm
@@ -0,0 +1,260 @@
+bcm_num_cos=8
+bcm_stat_interval=2000000
+bcm_tunnel_term_compatible_mode=1
+cdma_timeout_usec=3000000
+core_clock_frequency=668
+flow_init_mode=0
+ifa_enable=0
+ifp_inports_support_enable=1
+ipv6_lpm_128b_enable=0x1
+l2xmsg_mode=1
+
+#Default L3 profile
+
+l2_mem_entries=32768
+l3_alpm_enable=2
+l3_alpm_ipv6_128b_bkt_rsvd=1
+l3_max_ecmp_mode=1
+l3_mem_entries=16348
+lpm_scaling_enable=0
+memlist_enable=1
+reglist_enable=1
+scache_filename=/tmp/brcm_bcm_scache
+schan_intr_enable=0
+stable_size=0x5500000
+tdma_timeout_usec=3000000
+
+pfc_deadlock_seq_control=1
+
+#Port and PHY configs
+
+pbmp_xport_xe=0x1FFFFFFFFFFFFFFE
+port_gmii_mode_33=1
+port_gmii_mode_17=1
+port_gmii_mode_1=1
+portmap_1=1:1
+portmap_2=2:1
+portmap_3=3:1
+portmap_4=4:1
+portmap_5=5:1
+portmap_6=6:1
+portmap_7=7:1
+portmap_8=8:1
+portmap_9=9:1
+portmap_10=10:1
+portmap_11=11:1
+portmap_12=12:1
+portmap_13=13:1
+portmap_14=14:1
+portmap_15=15:1
+portmap_16=16:1
+portmap_17=17:1
+portmap_18=18:1
+portmap_19=19:1
+portmap_20=20:1
+portmap_21=21:1
+portmap_22=22:1
+portmap_23=23:1
+portmap_24=24:1
+portmap_25=25:1
+portmap_26=26:1
+portmap_27=27:1
+portmap_28=28:1
+portmap_29=29:1
+portmap_30=30:1
+portmap_31=31:1
+portmap_32=32:1
+portmap_33=33:1
+portmap_34=34:1
+portmap_35=35:1
+portmap_36=36:1
+portmap_37=37:1
+portmap_38=38:1
+portmap_39=39:1
+portmap_40=40:1
+portmap_41=41:1
+portmap_42=42:1
+portmap_43=43:1
+portmap_44=44:1
+portmap_45=45:1
+portmap_46=46:1
+portmap_47=47:1
+portmap_48=48:1
+portmap_49=64:10
+portmap_50=63:10
+portmap_51=62:10
+portmap_52=61:10
+portmap_53=69:100
+portmap_57=73:100
+phy_chain_tx_lane_map_physical{33.0}=0x2301
+phy_chain_rx_lane_map_physical{33.0}=0x2301
+phy_port_primary_and_offset_1=0x0100
+phy_port_primary_and_offset_2=0x0101
+phy_port_primary_and_offset_3=0x0102
+phy_port_primary_and_offset_4=0x0103
+phy_port_primary_and_offset_5=0x0104
+phy_port_primary_and_offset_6=0x0105
+phy_port_primary_and_offset_7=0x0106
+phy_port_primary_and_offset_8=0x0107
+phy_port_primary_and_offset_9=0x0900
+phy_port_primary_and_offset_10=0x0901
+phy_port_primary_and_offset_11=0x0902
+phy_port_primary_and_offset_12=0x0903
+phy_port_primary_and_offset_13=0x0904
+phy_port_primary_and_offset_14=0x0905
+phy_port_primary_and_offset_15=0x0906
+phy_port_primary_and_offset_16=0x0907
+phy_port_primary_and_offset_17=0x1200
+phy_port_primary_and_offset_18=0x1201
+phy_port_primary_and_offset_19=0x1202
+phy_port_primary_and_offset_20=0x1203
+phy_port_primary_and_offset_21=0x1204
+phy_port_primary_and_offset_22=0x1205
+phy_port_primary_and_offset_23=0x1206
+phy_port_primary_and_offset_24=0x1207
+phy_port_primary_and_offset_25=0x2000
+phy_port_primary_and_offset_26=0x2001
+phy_port_primary_and_offset_27=0x2002
+phy_port_primary_and_offset_28=0x2003
+phy_port_primary_and_offset_29=0x2004
+phy_port_primary_and_offset_30=0x2005
+phy_port_primary_and_offset_31=0x2006
+phy_port_primary_and_offset_32=0x2007
+phy_port_primary_and_offset_33=0x2900
+phy_port_primary_and_offset_34=0x2901
+phy_port_primary_and_offset_35=0x2902
+phy_port_primary_and_offset_36=0x2903
+phy_port_primary_and_offset_37=0x2904
+phy_port_primary_and_offset_38=0x2905
+phy_port_primary_and_offset_39=0x2906
+phy_port_primary_and_offset_40=0x2907
+phy_port_primary_and_offset_41=0x3200
+phy_port_primary_and_offset_42=0x3201
+phy_port_primary_and_offset_43=0x3202
+phy_port_primary_and_offset_44=0x3203
+phy_port_primary_and_offset_45=0x3204
+phy_port_primary_and_offset_46=0x3205
+phy_port_primary_and_offset_47=0x3206
+phy_port_primary_and_offset_48=0x3207
+port_phy_addr_1=0x0
+port_phy_addr_2=0x1
+port_phy_addr_3=0x2
+port_phy_addr_4=0x3
+port_phy_addr_5=0x4
+port_phy_addr_6=0x5
+port_phy_addr_7=0x6
+port_phy_addr_8=0x7
+port_phy_addr_9=0x9
+port_phy_addr_10=0xa
+port_phy_addr_11=0xb
+port_phy_addr_12=0xc
+port_phy_addr_13=0xd
+port_phy_addr_14=0xe
+port_phy_addr_15=0xf
+port_phy_addr_16=0x10
+port_phy_addr_17=0x12
+port_phy_addr_18=0x13
+port_phy_addr_19=0x14
+port_phy_addr_20=0x15
+port_phy_addr_21=0x16
+port_phy_addr_22=0x17
+port_phy_addr_23=0x18
+port_phy_addr_24=0x19
+port_phy_addr_25=0x20
+port_phy_addr_26=0x21
+port_phy_addr_27=0x22
+port_phy_addr_28=0x23
+port_phy_addr_29=0x24
+port_phy_addr_30=0x25
+port_phy_addr_31=0x26
+port_phy_addr_32=0x27
+port_phy_addr_33=0x29
+port_phy_addr_34=0x2a
+port_phy_addr_35=0x2b
+port_phy_addr_36=0x2c
+port_phy_addr_37=0x2d
+port_phy_addr_38=0x2e
+port_phy_addr_39=0x2f
+port_phy_addr_40=0x30
+port_phy_addr_41=0x32
+port_phy_addr_42=0x33
+port_phy_addr_43=0x34
+port_phy_addr_44=0x35
+port_phy_addr_45=0x36
+port_phy_addr_46=0x37
+port_phy_addr_47=0x38
+port_phy_addr_48=0x39
+port_phy_addr_49=0x40
+phy_force_firmware_load_50=0x01
+port_phy_addr_50=0x41
+phy_force_firmware_load_51=0x01
+port_phy_addr_51=0x42
+phy_force_firmware_load_52=0x01
+port_phy_addr_52=0x43
+phy_pcs_repeater_49=0x01
+phy_pcs_repeater_50=0x01
+phy_pcs_repeater_51=0x01
+phy_pcs_repeater_52=0x01
+dport_map_port_1=1
+dport_map_port_2=2
+dport_map_port_3=3
+dport_map_port_4=4
+dport_map_port_5=5
+dport_map_port_6=6
+dport_map_port_7=7
+dport_map_port_8=8
+dport_map_port_9=9
+dport_map_port_10=10
+dport_map_port_11=11
+dport_map_port_12=12
+dport_map_port_13=13
+dport_map_port_14=14
+dport_map_port_15=15
+dport_map_port_16=16
+dport_map_port_17=17
+dport_map_port_18=18
+dport_map_port_19=19
+dport_map_port_20=20
+dport_map_port_21=21
+dport_map_port_22=22
+dport_map_port_23=23
+dport_map_port_24=24
+dport_map_port_25=25
+dport_map_port_26=26
+dport_map_port_27=27
+dport_map_port_28=28
+dport_map_port_29=29
+dport_map_port_30=30
+dport_map_port_31=31
+dport_map_port_32=32
+dport_map_port_33=33
+dport_map_port_34=34
+dport_map_port_35=35
+dport_map_port_36=36
+dport_map_port_37=37
+dport_map_port_38=38
+dport_map_port_39=39
+dport_map_port_40=40
+dport_map_port_41=41
+dport_map_port_42=42
+dport_map_port_43=43
+dport_map_port_44=44
+dport_map_port_45=45
+dport_map_port_46=46
+dport_map_port_47=47
+dport_map_port_48=48
+dport_map_port_49=49
+dport_map_port_50=50
+dport_map_port_51=51
+dport_map_port_52=52
+dport_map_port_53=53
+dport_map_port_54=54
+dport_map_port_55=55
+dport_map_port_56=56
+dport_map_port_57=57
+dport_map_port_58=58
+dport_map_port_59=59
+dport_map_port_60=60
+
+sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc
+
diff --git a/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/linkscan_led_fw.bin b/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/linkscan_led_fw.bin
new file mode 100644
index 0000000000000000000000000000000000000000..e86cdc1ef6473e36a9c635a0576ef80de281e3ce
GIT binary patch
literal 6100
zcma)A3wTpip8wyQcbc}LR7p!(Zqk;fwP1><MG<dv;WX(3LdS2mAnFa);ifz$%+B!P
zj-RB(f%1~@a5kWRi|)>BeODy2<0Fzf$^h#+H!Z9<WyX9vx^Y!7!bp-na`%643X3zl
ze%pTM=6@dl|2gOPf1Lk05CG@^03VhIv3%FxL)Ue#LAn=<|GJ`b|BO(nOJm@Mmh}{N
zpzK`o>Oa7pZm{+83*C3Lx_rGposIGZS^|;VI$*X#V66@wioj7W&gBOLZDL3;78z)R
zak*uPkNLrIC0>|F2z5fg%XBW`AK<t7?0&HE{!j~pbDkS}QGkYv@!4)*Vk8g^M6@I*
z7;RK)*;r*qov_%#FjVTRF>uTfUln@!MnC1-=x_FI6yD{VdA~sM9;=^!PJr1^XAn;d
zP<7B%K0M?b;L8&zkqbn(`A+!K$<uzQ*NY><Q!c}~cYLS)A>T>di9T@xf4BP7i2^c>
zoE8qcJ|6}q5Cs<C$QOM82}pR6meP+(26ynXp&yvw<<kDIE|&&ro1T;D<ClN97gASp
zRBC%BmqhFy#li$yzSmkJ=vgD%=c3{i*5$TkZ4fCV%iK~rC4oZ|FC!gDe~vUIwz(lH
z7juNP6Ss{>=|4(T)u;*_s<@4CIPTvi3o%C*DKZve{evkP3z0sl$XJN{9ZXOS(OZ>K
z^Reg6sZsNgjwqw%<0!d+eVP~7Wz%;BTAUFR(cqk-w0OA_*PurFv;-^6Q}nY6eRb56
zQ=?2oZ?``~rC!T|gBFd5w>fG;ea#qScyJVmELsgPQu+x=YLc340^Q`sx;aWIBex2>
zT=Y4aE6~CUtOW!!_6A!1vYl31Q?~;kY7lr0O9U|vQDz7=qP42c2iH`YLo=#X>--zm
z{_TUl4cH6DQ@dQM;jpFOr5)BKz`vq=hb36q>!L=kY9kQQ*fX9I8mhhA5{sANIfrFv
zE!647=5^Xr`&??VcOBGGVr*T1OSjeBaAEX<J19u$mvXX=d>#3`qi@h5$hre27uDDd
z^e1jAWzT+!NZ%u=$!B~u?tO(s5gvxveqFFw;LQ%|BQqoL3D6?KZ8*wVA*EX+zX1EF
z)Y*)d0AowMs^3jCHS{5|Z4T|{{?+2OfxVf#&oYfTY9Hp-dH=c0Z&}9EPwwJR@(+>%
zA5`t~6|8>W*J*8Ay^zrLpO3OuIMna@{fO*6-t6&qs^$o4L@!pNM&9;NKCms}n|(NQ
zu7>}Iq&f00t)0R?7d@g@G^4SX&|dD<);>hV%}uv-p&!$tM(G1PRqbHBoW;^<UF@Ul
zGoyO6N^|6w-<D8aP4nE5cCbU4x7x=|C#=O`Th28jSDV5m+krU(b;YCM_HN-BSHZAG
z;W^Nr=U^?r>F(>6N9ET9b>`7M${eO)P1Q`gi`&r#_L#+6wSr?UeckVLn@ONW9vf)M
zufMl7Xz|*YWAD|LN3OLvoPm~1q)4%Oe-1)0r&x3ny;DcN^i!#o8CQjkI8a09bLgk2
z-x!xs){%)eVbp5H{$r$yU>p;SiN|3Ld3(in_~Y`qe%9)-ZgWALX7;%*jqpO9KZq7c
zk3cFZ^;>x!!jugJJqL&MXw{kM<;eCy4d}&-{`o>cc+926SP|n4gDGXUv81Nfj~1al
z_$(al+6t$=^*BSf^;vm_>R-DqkI>;Dlsc)@{Tcls)Gu!kOYO*!Iw9%9^kGWSFdvqg
z5;V#@ll;GAIB}J+vivF!;wqiIHXKc6BBewJ1`!VGNg*PW^F!(bsks6eQ$j{L6TRcQ
zwe-RBUH=G|y#2T)2-gWgX!OeaOGm2O`v!}N2Fzj;O1bDqtW(cRu8Kwl-v-22tKh4-
zwr2=K>X5`%Kqw%*Mdl&ORLGdvg(#1AZHJNNHz_D@RZxZ}54pY`*(jW})cNx}xCM6*
z;Hj|s$siOZ09LU8CM*+o18^#U{^<aXt2{c@neIwx$i~$PXrM)$Bb>+SjbtBUy&KAx
z%UFA?effC~%lZW7g=8S22A!De$hqs#K1`E{dYnqg5uuKZq35fxMI|z*gYNM_w7Zfw
z1VM8C#3`j$PRdc^@L+iu9Jh$64yfKhOt0`1Yn9Sxq-UU~tJ_MmpSzt-w#&@XY{2_>
zUQ@%xQK%6pnEfJHLYA;R_HAjwiXKw3qJT_iY4(7N7Ts(ww_y1u>%6%aM$5zNt<-YU
zoKHr9nTeRHP*-Eg6h`ztgKh>=9!Udth;<bjq*J*%V#ePu@mJqyLMn-|jUpRJAF$R}
zy(Y)lC?niLhKgCB><|h;ZC9st3lwv+yiC_nv8n!>5vV=_&1KH6(nd&~%ynB$4Od3r
zKx_ab<<guQwG63Ga||iOwa5`<45Q7fZNOLwO`P+4VWpR~uEv?Nqc3}2K7vS0n9(a<
zX@6}{2WqjY0#XNZ6h<G0+=>!p8-mo%To9ZN`Xkv6FDHSapVKHS-lMD-s(%TovQiwk
zDMvroZS7xfYWN1xD0;CMclD4m#%ZUYD<6Q=yj;->z?8q-3wz3b)HUbfPW=U4J;z#C
zdJ7zX9ziSa+P2iAFGE}Ih1FfG^+(D|d)uMLIbTpTm(EdS0OobAw;EZy*EHwyHGNSb
zO3~MU;)tKPf86SH!itg=D%6@0wWbyWt<9`+UO#76H22x)I`{0C<uU86PSoG|(Vq4m
zw0#C~?3qBHu(|Y|0Q=?oh6x$<p()f0r%-P~q$ek7TR&&Q+++dPAa}oe0hxbT*2Rq6
z{piy=QhIyW(n6vp;82SUqWj4tjVG9sWbjl*9yMxfQnuc6*Cg4nHagknt|v&Lq)U^T
zXeL5rDX1Y?#ygX$DH(SymDlXVQRWFaOffVE`}6hE30dk(-;z2wdD}Iqzg46*UMKbM
zC)HC@Yp+TDbo_sikZ1X?aan5Lx1|1TlDQ`JDU_Ou>>UK=#${?!7&1Mtw%tXVkTW)3
z^gP%cNWD2;6prZ@$4&Tc7UdCg|KPakFpcXs?N=+Kj*ScCMvN!d=OC+=05o81abUSV
z_n43*$%$=JT9+#ff#b&blBJ71Tfw>DRM$6MJ!H76ke$ZvaZw^weF^Q~<oIe78dRcy
z5v3kE<TWf*R=HkTMW3<?S@RpmZ*j{ySUXl2E=GUIMV!kTJLnMg937U@=O)xpbcPCJ
z7J*txPf!k%NIUKjRgSwvwSyH^)t_(_M%N0|a4x!lRJo<}3z%DL;tPlk>0cm?*-WZC
zV<QyGyECVT9#Sag5vU!9!xKy&S5g5}nADGdn9TQ;VP9U``Fh28Bxxf~+|PSCeIieN
zno~_t1(F(mA-<m6jrh$+oMcR846o*PsmP;Cq55QvlfSK^k^iZivYDDFo=&I*x`7hc
zSB?#1yyo>po#=(VWp@jIgBXTgnNhhH=E(V2DyqlWAmaly>y}c?t^C?$5bA|fWx)lk
z_21S&$mvLb1l4QYRF%!rLw<m}e^-KVbLGu-s^K8S%7RVruIaYAG3%qMsOKN>Jm99D
zkkUsngEoxb=MMG&)m)7Jtz(OuSt_)Vrx+)nLt8`7s?}nwWi2-lQ%IL^qJ8#fzyTsv
zYYK0&4!XWM4>x}gPaHkjh3I;$qSsWH9aUF(JRV#{FV4{XdpRqXBc^QKe&oJgv{TEi
z=6OFS&O{ShfSk*@D{ppa&fVJD4?#<?DfUD86pC@+sQg1)<;OFmBFVDFu!Z_~CROz&
z`&+EvZF!4qnRXmDkmF_b!VkzM!(na{RnKpmdAC3@gRBniv7D>N8`Z`o@BaZKdH9Iy
z?eoCAk!*_Ku0^)e-p(4dBIPI*g8*fCy9+f%0Z$DJu23yfNKHqIiYKs#wqYb-w22$s
z_*)^5rEE0j!y6Fgrl`(i6rdhu+51?xK+B#mbw@I(rkNSEg}2Z)pc!$a%?+>(XrP<W
z)$C?~Uk8EKTZ8*3Gu{Jc*L!ZlQ{(k4*c~0R_15!&Xx;`#v$crlUc8&=5pCHPca34h
zIxC+-fhcABCP^t4`q`Mk=PmThF%=o$XSU{RgJT-doXyjF#~gS&mD0~l$R|DKt+<n1
zRz8c>P!eZw=TDF8J>WRW8%2}HfH&0wCChI1scg->ls=GQFiZZcIDt8d&IDk^{oYi7
z`^C(GLL_V5fffS;D$H9M7QY1w4G}4QQQDz4nAnwgd&62%sku5KYIVcrKufttACSK>
zok2J)bmDmtE2g>Ae4yn9*=Bwk)5VGdEhV0q)*$TkcN#jWSP{+b#M^wKyBqUTcw8PK
zYtU0U9uKtWl-A&1v|?OCe{I4wFUFFJ9B7?Yb3)kPcA)(w%{~F<mWkirOw}&pz8~1O
zQ@8WV%uUu~<OBb4O(nafa1pnLY|+eSj~f?pANX{SzRXG5Ee4rB;m>o@dCuLs-FeQU
zp1<ZSTCLl2m9uE|iJm;CTH)OOxc2emGq+gZBFlPyrJ2QUD!iRTTi4XGzcSv=EnBVK
z`wDkOyU8HaC)VaU^$KUpI_<hV=idK?bMNYH>#lO{U43F5%$<SzG%K9i^}p+Jt)Ip2
zpZS{R-oj4nEUpvh+i#q~{cd$|{VQBd%Nle@EAfbFSxSW<q$bXQl-5e5!@*N%O_U_?
zi`@hK;#SPSC{LNu_dd^Bcl%m>8poAUDLt8^Y6tndRSSq9K<caP>*fLc{UR%8CP(oV
zW{2hd2N_2O^Bg!NrEkn?fL1I$7p2e-@dYERA}M}uD`sX`b7j?N+jUBmw`JwiU{Dwm
z7H~tj7H2@d&&s}4)gh&ab2Hn)VMhOyX?(57mAieyK#K)^i<0=wQu;%sRZDnW1<y17
zT-qu*(OdFfvNj{7A44yhrg({QOov{g_ZdVR-b77PK0>39<WQRIBMZ@{s0<#Ux|sAx
zE5IWpZ*L!$VtW(5ca`8dp}bZ=YFqYdwu8G$?Z`gvwv&A3c_f?9JO^-Z0n8_Lq~E=W
zsD;wodIz0k;e1F5S+=s-@Sb)Dn942`Iq|%FAWIR7fjWGr5C>R_qY?v{SKIhTL<~|Z
zvrU9XWQU|2W<P4YIhM{ZB657@P}26JjFOq&m5m);fRUyyXG4i>R?eO7%I5Dn|0KzI
zlgwF!ycWz)XJ=(Tz&8W7viIm6IJ=ado<km-&pySq1G(_dK}wy41kd%931^Vf#$0|?
z#o0PsgOuJR$-C4N%<piAP%WQ2=?rDtK|fRpp?(*PG~i1Eq%LGy+T5OZ%EPW^vE)2y
z-C7=U-6pEf8yyW|w}Xi{BwTKb#VNX4MORr|V~21}f^|<X?{nQO>d!B7n=KA;5%v|t
z_1HHfu@Fbsh<9QO9WTI^qC^8}R8V;*lgFzL@xr@9m`XsHw!7~6DyhQSSW=DObW)4o
zKPPqg{W@vD@5Q7Mzh7Xc3O3m1$DM7+sG<0bYBoH5g@ZW;(Sf_znZb)(>cxykTX5sF
znGDF;YyQ4&l;j*kzPZoAx0RA9da;zjY(#EdDP5kT1nFXOzH&SHImYHp)Qxtx7|VbU
z;HL!OGn}G&Op=cMha_dHDG=V1q|`Y{;vddQu}c$@Gg3fg&tmXB#E>W?XW6G+nvn|f
z1nZeugI~7n2GUsxbG|<BjH*Zh_oPlG8WQ?bCA0J~b^X||Dp9am6_9V3ot4?)K+Et^
zDnZNj%5kiL{R-ZbrV}G(>Seg@l;RuChz4g=5lGx?J>b#|f4S=9DyE!@L&KFg&SHZK
zwo<jZgf8bimD#iMdx(mt?D_y0<ypqgTChcnZ$a9nn#7+3-TOCjriI}a^ZaA3^hhoZ
zlU*|aHe+!f`!VURtl8XceZd98739JD?u9>DoNrlL0MM%)RbmOgy}+z8L6zursm>XR
zM}WF)9O{kYbm6h`r(Ehd2o{T(HxoMH<so6=p-v~#LP7ZfmnvQ$3|na4BQ*2o=sk#e
zDpKGa(w~CTWiY$6wK$=|m%)OOT`tW>tI9dc62bW!{hg5Dgy}pTQzz&OGv+^E#?i*{
zZM13X1uhlUwrbsGUfWtyKCB;x#W9L$;y+Awp?rA`wHGjO0MH5jNz}m*)Q{l_C%?;5
r32LZh7SzipUVi`b`|m0o-h^13!6LsQJYocJBmG@}mEYC*|LFT~Y{;3K

literal 0
HcmV?d00001

diff --git a/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/pg_profile_lookup.ini b/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/pg_profile_lookup.ini
new file mode 100644
index 000000000000..6d91d03ae684
--- /dev/null
+++ b/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/pg_profile_lookup.ini
@@ -0,0 +1,17 @@
+# PG lossless profiles.
+# speed cable size      xon     xoff   threshold xon_offset
+  10000  5m   9427       0     50176    1        3584
+  25000  5m   9427       0     50176    1        3584
+  40000  5m   9427       0     50176    1        3584
+  50000  5m   9427       0     50176    1        3584
+ 100000  5m   9427       0     50176    1        3584
+  10000  40m  9427       0     50176    1        3584
+  25000  40m  9427       0     50176    1        3584
+  40000  40m  9427       0     50176    1        3584
+  50000  40m  9427       0     50176    1        3584
+ 100000  40m  9427       0     50176    1        3584
+  10000  300m 9427       0     50176    1        3584
+  25000  300m 9427       0     50176    1        3584
+  40000  300m 9427       0     50176    1        3584
+  50000  300m 9427       0     50176    1        3584
+ 100000  300m 9427       0     50176    1        3584
diff --git a/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/port_config.ini b/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/port_config.ini
new file mode 100644
index 000000000000..fd37efc9332e
--- /dev/null
+++ b/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/port_config.ini
@@ -0,0 +1,55 @@
+# name        lanes                   alias                    index     speed   autoneg
+Ethernet0       1     oneGigE1/1           1     1000     1
+Ethernet1       2     oneGigE1/2           2     1000     1
+Ethernet2       3     oneGigE1/3           3     1000     1
+Ethernet3       4     oneGigE1/4           4     1000     1
+Ethernet4       5     oneGigE1/5           5     1000     1
+Ethernet5       6     oneGigE1/6           6     1000     1
+Ethernet6       7     oneGigE1/7           7     1000     1
+Ethernet7       8     oneGigE1/8           8     1000     1
+Ethernet8       9     oneGigE1/9           9     1000     1
+Ethernet9       10    oneGigE1/10          10    1000     1
+Ethernet10      11    oneGigE1/11          11    1000     1
+Ethernet11      12    oneGigE1/12          12    1000     1
+Ethernet12      13    oneGigE1/13          13    1000     1
+Ethernet13      14    oneGigE1/14          14    1000     1
+Ethernet14      15    oneGigE1/15          15    1000     1
+Ethernet15      16    oneGigE1/16          16    1000     1
+Ethernet16      17    oneGigE1/17          17    1000     1
+Ethernet17      18    oneGigE1/18          18    1000     1
+Ethernet18      19    oneGigE1/19          19    1000     1
+Ethernet19      20    oneGigE1/20          20    1000     1
+Ethernet20      21    oneGigE1/21          21    1000     1
+Ethernet21      22    oneGigE1/22          22    1000     1
+Ethernet22      23    oneGigE1/23          23    1000     1
+Ethernet23      24    oneGigE1/24          24    1000     1
+Ethernet24      25    oneGigE1/25          25    1000     1
+Ethernet25      26    oneGigE1/26          26    1000     1
+Ethernet26      27    oneGigE1/27          27    1000     1
+Ethernet27      28    oneGigE1/28          28    1000     1
+Ethernet28      29    oneGigE1/29          29    1000     1
+Ethernet29      30    oneGigE1/30          30    1000     1
+Ethernet30      31    oneGigE1/31          31    1000     1
+Ethernet31      32    oneGigE1/32          32    1000     1
+Ethernet32      33    oneGigE1/33          33    1000     1
+Ethernet33      34    oneGigE1/34          34    1000     1
+Ethernet34      35    oneGigE1/35          35    1000     1
+Ethernet35      36    oneGigE1/36          36    1000     1
+Ethernet36      37    oneGigE1/37          37    1000     1
+Ethernet37      38    oneGigE1/38          38    1000     1
+Ethernet38      39    oneGigE1/39          39    1000     1
+Ethernet39      40    oneGigE1/40          40    1000     1
+Ethernet40      41    oneGigE1/41          41    1000     1
+Ethernet41      42    oneGigE1/42          42    1000     1
+Ethernet42      43    oneGigE1/43          43    1000     1
+Ethernet43      44    oneGigE1/44          44    1000     1
+Ethernet44      45    oneGigE1/45          45    1000     1
+Ethernet45      46    oneGigE1/46          46    1000     1
+Ethernet46      47    oneGigE1/47          47    1000     1
+Ethernet47      48    oneGigE1/48          48    1000     1
+Ethernet48      64    tenGigE1/49          49    10000    0
+Ethernet49      63    tenGigE1/50          50    10000    0
+Ethernet50      62    tenGigE1/51          51    10000    0
+Ethernet51      61    tenGigE1/52          52    10000    0
+Ethernet52      69,70,71,72           hundredGigE1/53     53      100000           0
+Ethernet56      73,74,75,76           hundredGigE1/54     54      100000           0
diff --git a/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/qos.json.j2 b/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/qos.json.j2
new file mode 100644
index 000000000000..ee67c6e26221
--- /dev/null
+++ b/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/qos.json.j2
@@ -0,0 +1 @@
+{%- include 'qos_config_t1.j2' %}
diff --git a/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/qos_config_t1.j2 b/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/qos_config_t1.j2
new file mode 100644
index 000000000000..5fe5324a85c1
--- /dev/null
+++ b/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/qos_config_t1.j2
@@ -0,0 +1,175 @@
+{%- set PORT_ALL = [] %}
+{%- for port in PORT %}
+    {%- if PORT_ALL.append(port) %}{% endif %}
+{%- endfor %}
+{%- if PORT_ALL | sort_by_port_index %}{% endif %}
+
+{%- set port_names_list_all = [] %}
+{%- for port in PORT_ALL %}
+    {%- if port_names_list_all.append(port) %}{% endif %}
+{%- endfor %}
+{%- set port_names_all = port_names_list_all | join(',') -%}
+
+
+{%- set PORT_ACTIVE = [] %}
+{%- if DEVICE_NEIGHBOR is not defined %}
+    {%- set PORT_ACTIVE = PORT_ALL %}
+{%- else %}
+    {%- for port in DEVICE_NEIGHBOR.keys() %}
+        {%- if PORT_ACTIVE.append(port) %}{%- endif %}
+    {%- endfor %}
+{%- endif %}
+{%- if PORT_ACTIVE | sort_by_port_index %}{% endif %}
+
+{%- set port_names_list_active = [] %}
+{%- for port in PORT_ACTIVE %}
+    {%- if port_names_list_active.append(port) %}{%- endif %}
+{%- endfor %}
+{%- set port_names_active = port_names_list_active | join(',') -%}
+
+
+{%- set pfc_to_pg_map_supported_asics = ['mellanox', 'barefoot', 'marvell'] -%}
+
+
+{
+{% if generate_tc_to_pg_map is defined %}
+    {{- generate_tc_to_pg_map() }}
+{% else %}
+    "TC_TO_PRIORITY_GROUP_MAP": {
+        "AZURE": {
+            "0": "0",
+            "1": "0",
+            "2": "0",
+            "3": "3",
+            "4": "4",
+            "5": "0",
+            "6": "0",
+            "7": "7"
+        }
+    },
+{% endif %}
+    "MAP_PFC_PRIORITY_TO_QUEUE": {
+        "AZURE": {
+            "0": "0",
+            "1": "1",
+            "2": "2",
+            "3": "3",
+            "4": "4",
+            "5": "5",
+            "6": "6",
+            "7": "7"
+        }
+    },
+    "TC_TO_QUEUE_MAP": {
+        "AZURE": {
+            "0": "0",
+            "1": "1",
+            "2": "2",
+            "3": "3",
+            "4": "4",
+            "5": "5",
+            "6": "6",
+            "7": "7"
+        }
+    },
+    "DSCP_TO_TC_MAP": {
+        "AZURE": {
+            "0" : "1",
+            "1" : "1",
+            "2" : "1",
+            "3" : "3",
+            "4" : "4",
+            "5" : "2",
+            "6" : "1",
+            "7" : "1",
+            "8" : "0",
+            "9" : "1",
+            "10": "1",
+            "11": "1",
+            "12": "1",
+            "13": "1",
+            "14": "1",
+            "15": "1",
+            "16": "1",
+            "17": "1",
+            "18": "1",
+            "19": "1",
+            "20": "1",
+            "21": "1",
+            "22": "1",
+            "23": "1",
+            "24": "1",
+            "25": "1",
+            "26": "1",
+            "27": "1",
+            "28": "1",
+            "29": "1",
+            "30": "1",
+            "31": "1",
+            "32": "1",
+            "33": "1",
+            "34": "1",
+            "35": "1",
+            "36": "1",
+            "37": "1",
+            "38": "1",
+            "39": "1",
+            "40": "1",
+            "41": "1",
+            "42": "1",
+            "43": "1",
+            "44": "1",
+            "45": "1",
+            "46": "5",
+            "47": "1",
+            "48": "6",
+            "49": "1",
+            "50": "1",
+            "51": "1",
+            "52": "1",
+            "53": "1",
+            "54": "1",
+            "55": "1",
+            "56": "1",
+            "57": "1",
+            "58": "1",
+            "59": "1",
+            "60": "1",
+            "61": "1",
+            "62": "1",
+            "63": "1"
+        }
+    },
+    "SCHEDULER": {
+        "scheduler.0": {
+            "type"  : "DWRR",
+            "weight": "14"
+        },
+        "scheduler.1": {
+            "type"  : "DWRR",
+            "weight": "15"
+        }
+    },
+{% if asic_type in pfc_to_pg_map_supported_asics  %}
+    "PFC_PRIORITY_TO_PRIORITY_GROUP_MAP": {
+        "AZURE": {
+            "3": "3",
+            "4": "4"
+        }
+    },
+{% endif %}
+    "PORT_QOS_MAP": {
+{% for port in PORT_ACTIVE %}
+        "{{ port }}": {
+            "dscp_to_tc_map"  : "[DSCP_TO_TC_MAP|AZURE]",
+            "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]",
+            "tc_to_pg_map"    : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]",
+            "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]",
+{% if asic_type in pfc_to_pg_map_supported_asics %}
+            "pfc_to_pg_map"   : "[PFC_PRIORITY_TO_PRIORITY_GROUP_MAP|AZURE]",
+{% endif %}
+            "pfc_enable"      : "3,4"
+        }{% if not loop.last %},{% endif %}
+{% endfor %}
+    }
+}
diff --git a/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/sai.profile b/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/sai.profile
new file mode 100644
index 000000000000..8acb22ae32f2
--- /dev/null
+++ b/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/sai.profile
@@ -0,0 +1 @@
+SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/hx5-n3248te-48x1G+4x10G.config.bcm
diff --git a/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/sai_preinit_cmd.soc b/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/sai_preinit_cmd.soc
new file mode 100644
index 000000000000..4d62900f898f
--- /dev/null
+++ b/device/dell/x86_64-dellemc_n3248te_c3338-r0/DellEMC-N3248TE/sai_preinit_cmd.soc
@@ -0,0 +1,2 @@
+m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin
+m0 load 0 0x3800 /usr/share/sonic/hwsku/custom_led.bin
diff --git a/device/dell/x86_64-dellemc_n3248te_c3338-r0/default_sku b/device/dell/x86_64-dellemc_n3248te_c3338-r0/default_sku
new file mode 100644
index 000000000000..59ca9b54544a
--- /dev/null
+++ b/device/dell/x86_64-dellemc_n3248te_c3338-r0/default_sku
@@ -0,0 +1 @@
+DellEMC-N3248TE t1
diff --git a/device/dell/x86_64-dellemc_n3248te_c3338-r0/init_cfg.json b/device/dell/x86_64-dellemc_n3248te_c3338-r0/init_cfg.json
new file mode 100644
index 000000000000..dc933239006c
--- /dev/null
+++ b/device/dell/x86_64-dellemc_n3248te_c3338-r0/init_cfg.json
@@ -0,0 +1,13 @@
+{
+  "FEATURE": {
+    "tam": {
+        "state": "disabled"
+    },
+    "telemetry": {
+        "state": "disabled"
+    },
+    "nat": {
+        "state": "disabled"
+    }
+  }
+}
diff --git a/device/dell/x86_64-dellemc_n3248te_c3338-r0/installer.conf b/device/dell/x86_64-dellemc_n3248te_c3338-r0/installer.conf
new file mode 100644
index 000000000000..8e3add013c31
--- /dev/null
+++ b/device/dell/x86_64-dellemc_n3248te_c3338-r0/installer.conf
@@ -0,0 +1,3 @@
+CONSOLE_PORT=0x3f8
+CONSOLE_DEV=0
+VAR_LOG_SIZE=512
diff --git a/device/dell/x86_64-dellemc_n3248te_c3338-r0/led_proc_init.soc b/device/dell/x86_64-dellemc_n3248te_c3338-r0/led_proc_init.soc
new file mode 100644
index 000000000000..c909fe5e9fe5
--- /dev/null
+++ b/device/dell/x86_64-dellemc_n3248te_c3338-r0/led_proc_init.soc
@@ -0,0 +1,7 @@
+# LED microprocessor initialization for Dell N3248TE
+#
+#
+#Led0
+#led auto on
+m0 load 0 0x3800 /usr/share/sonic/hwsku/custom_led.bin
+led start
diff --git a/device/dell/x86_64-dellemc_n3248te_c3338-r0/plugins/eeprom.py b/device/dell/x86_64-dellemc_n3248te_c3338-r0/plugins/eeprom.py
new file mode 100644
index 000000000000..bf4703f05d9f
--- /dev/null
+++ b/device/dell/x86_64-dellemc_n3248te_c3338-r0/plugins/eeprom.py
@@ -0,0 +1,22 @@
+#!/usr/bin/python3
+
+#############################################################################
+# Dell S3000
+#
+# Platform and model specific eeprom subclass, inherits from the base class,
+# and provides the followings:
+# - the eeprom format definition
+# - specific encoder/decoder if there is special need
+#############################################################################
+
+try:
+    from sonic_eeprom import eeprom_tlvinfo
+except ImportError as e:
+    raise ImportError (str(e) + "- required module not found")
+
+
+class board(eeprom_tlvinfo.TlvInfoDecoder):
+
+    def __init__(self, name, path, cpld_root, ro):
+        self.eeprom_path = "/sys/class/i2c-adapter/i2c-2/2-0050/eeprom"
+        super(board, self).__init__(self.eeprom_path, 0, '', True)
diff --git a/device/dell/x86_64-dellemc_n3248te_c3338-r0/plugins/fanutil.py b/device/dell/x86_64-dellemc_n3248te_c3338-r0/plugins/fanutil.py
new file mode 100644
index 000000000000..c8f277cb211b
--- /dev/null
+++ b/device/dell/x86_64-dellemc_n3248te_c3338-r0/plugins/fanutil.py
@@ -0,0 +1,73 @@
+#
+# fanutil.py
+# Platform-specific FAN status interface for SONiC
+#
+
+import commands
+import os
+import sys
+
+SENSORS_CMD = "docker exec -i pmon /usr/bin/sensors"
+DOCKER_SENSORS_CMD = "/usr/bin/sensors"
+
+
+try:
+    from sonic_fan.fan_base import FanBase
+except ImportError as e:
+    raise ImportError(str(e) + "- required module not found")
+
+
+class FanUtil(FanBase):
+    """Platform-specific FanUtil class"""
+    _fan_mapping = {
+        1 : '0',
+        2 : '1',
+        3 : '2'
+    }
+
+    def __init__(self):
+        FanBase.__init__(self)
+
+    def isDockerEnv(self):
+        num_docker = open('/proc/self/cgroup', 'r').read().count(":/docker")
+        if num_docker > 0:
+            return True
+
+    def get_num_fans(self):
+       N3248TE_MAX_FANTRAYS = 3
+       return N3248TE_MAX_FANTRAYS
+
+    def get_presence(self, idx):
+       sysfs_path = "/sys/devices/platform/dell-n3248te-cpld.0/fan" + self._fan_mapping[idx] + "_prs"
+       return int(open(sysfs_path).read(), 16)
+
+    def get_direction(self, idx):
+       sysfs_path = "/sys/devices/platform/dell-n3248te-cpld.0/fan" + self._fan_mapping[idx] + "_dir"
+       return open(sysfs_path).read()
+
+    def get_speed(self, idx):
+        dockerenv = self.isDockerEnv()
+        if not dockerenv:
+            status, cmd_output = commands.getstatusoutput(SENSORS_CMD)
+        else :
+            status, cmd_output = commands.getstatusoutput(DOCKER_SENSORS_CMD)
+
+        if status:
+            print('Failed to execute sensors command')
+            sys.exit(0)
+        fan_id = 'Fan ' + str(idx)
+        found = False
+        for line in cmd_output.splitlines():
+            if line.startswith('emc2305-i2c-7-2c'):
+                found = True
+            if found and line.startswith(fan_id):
+                return line.split()[3]
+        return 0.0
+
+    def get_status(self, idx):
+       sysfs_path = "/sys/devices/platform/dell-n3248te-cpld.0/fan" + self._fan_mapping[idx] + "_prs"
+       return int(open(sysfs_path).read(), 16)
+
+
+    def set_speed(self, idx):
+       return False
diff --git a/device/dell/x86_64-dellemc_n3248te_c3338-r0/plugins/pcie.yaml b/device/dell/x86_64-dellemc_n3248te_c3338-r0/plugins/pcie.yaml
new file mode 100644
index 000000000000..dd8049268567
--- /dev/null
+++ b/device/dell/x86_64-dellemc_n3248te_c3338-r0/plugins/pcie.yaml
@@ -0,0 +1,16 @@
+- bus: '02'
+  dev: '00'
+  fn: '0'
+  id: '1533'
+  name: 'Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev
+    03)'
+- bus: '01'
+  dev: '00'
+  fn: '0'
+  id: b371
+  name: 'Ethernet controller: Broadcom Limited BCM56371 Switch ASIC (rev 02)'
+- bus: '00'
+  dev: '14'
+  fn: '0'
+  id: 19c2
+  name: 'SATA controller: Intel Corporation DNV SATA Controller 1 (rev 11)'
diff --git a/device/dell/x86_64-dellemc_n3248te_c3338-r0/plugins/psuutil.py b/device/dell/x86_64-dellemc_n3248te_c3338-r0/plugins/psuutil.py
new file mode 100644
index 000000000000..13e95ed2549d
--- /dev/null
+++ b/device/dell/x86_64-dellemc_n3248te_c3338-r0/plugins/psuutil.py
@@ -0,0 +1,191 @@
+#
+# psuutil.py
+# Platform-specific PSU status interface for SONiC
+#
+
+import commands
+import os
+import sys
+
+SENSORS_CMD = "docker exec -i pmon /usr/bin/sensors"
+DOCKER_SENSORS_CMD = "/usr/bin/sensors"
+
+try:
+    from sonic_psu.psu_base import PsuBase
+except ImportError as e:
+    raise ImportError(str(e) + "- required module not found")
+
+
+class PsuUtil(PsuBase):
+    """Platform-specific PSUutil class"""
+    _psu_mapping = {
+        1 : '0',
+        2 : '1'
+    }
+
+    def __init__(self):
+        PsuBase.__init__(self)
+
+    def isDockerEnv(self):
+        num_docker = open('/proc/self/cgroup', 'r').read().count(":/docker")
+        if num_docker > 0:
+            return True
+        else:
+            return False
+
+    def remove_nonnumeric(self, text):
+        digits='0123456789.'
+        return ''.join(c for c in text if c in digits)
+
+    def get_cpld_register(self, reg_name):
+        cpld_dir = "/sys/devices/platform/dell-n3248te-cpld.0/"
+        retval = 'ERR'
+        reg_file = cpld_dir +'/' + reg_name
+        if (not os.path.isfile(reg_file)):
+            return retval
+
+        try:
+            with open(reg_file, 'r') as fd:
+                retval = fd.read()
+        except Exception as error:
+            print("Unable to open ", reg_file, "file !")
+
+        retval = retval.rstrip('\r\n')
+        return retval
+
+    def get_num_psus(self):
+        """
+        Retrieves the number of PSUs available on the device
+        :return: An integer, the number of PSUs available on the device
+         """
+        N3248TE_MAX_PSUS = 2
+        return N3248TE_MAX_PSUS
+
+    def get_psu_status(self, index):
+        """
+        Retrieves the oprational status of power supply unit (PSU) defined
+                by index <index>
+        :param index: An integer, index of the PSU of which to query status
+        :return: Boolean, True if PSU is operating properly, False if PSU is\
+        faulty
+        """
+        status = 0
+        psu_status = self.get_cpld_register('psu'+self._psu_mapping[index]+'_status')
+        if (psu_status != 'ERR'):
+            status = int(psu_status, 10)
+
+        presence = self.get_psu_presence(index)
+
+        return (status & presence)
+
+    def get_psu_presence(self, index):
+        """
+        Retrieves the presence status of power supply unit (PSU) defined
+                by index <index>
+        :param index: An integer, index of the PSU of which to query status
+        :return: Boolean, True if PSU is plugged, False if not
+        """
+        status = 0
+        psu_presence = self.get_cpld_register('psu'+self._psu_mapping[index]+'_prs')
+        if (psu_presence != 'ERR'):
+            status = int(psu_presence, 10)
+
+        return status
+
+    def get_sensor(self):
+        dockerenv = self.isDockerEnv()
+        if not dockerenv:
+          status, cmd_output = commands.getstatusoutput(SENSORS_CMD)
+        else :
+          status, cmd_output = commands.getstatusoutput(DOCKER_SENSORS_CMD)
+
+        if status:
+            print('Failed to execute sensors command')
+            sys.exit(0)
+        return cmd_output
+
+    def get_output_current(self, index):
+        cmd_output= self.get_sensor()
+        sensor_name = 'dps460-i2c-10' if index == 1 else 'dps460-i2c-11'
+        found = False
+        for line in cmd_output.splitlines():
+            if line.startswith(sensor_name):
+                found = True
+            if found:
+                if 'Output Current' in line :
+                    return float(self.remove_nonnumeric(line.split()[2]))
+        return 0.0
+
+    def get_output_voltage(self, index):
+        cmd_output= self.get_sensor()
+        sensor_name = 'dps460-i2c-10' if index == 1 else 'dps460-i2c-11'
+        found = False
+        for line in cmd_output.splitlines():
+            if line.startswith(sensor_name):
+                found = True
+            if found:
+                if 'Output Voltage' in line :
+                    return float(self.remove_nonnumeric(line.split()[2]))
+        return 0.0
+
+    def get_fan_rpm(self, index, fan_index):
+        if fan_index > 1 : return 0.0
+        cmd_output= self.get_sensor()
+        sensor_name = 'dps460-i2c-10' if index == 1 else 'dps460-i2c-11'
+        found = False
+        for line in cmd_output.splitlines():
+            if line.startswith(sensor_name):
+                found = True
+            if found:
+                if 'Fan RPM' in line :
+                    return self.remove_nonnumeric(line.split()[2])
+        return 0.0
+
+    def get_output_power(self, index):
+        cmd_output= self.get_sensor()
+        sensor_name = 'dps460-i2c-10' if index == 1 else 'dps460-i2c-11'
+        found = False
+        for line in cmd_output.splitlines():
+            if line.startswith(sensor_name):
+                found = True
+            if found:
+                if 'Output Power' in line :
+                    return float(self.remove_nonnumeric(line.split()[2]))
+        return 0.0
+
+    def get_direction(self, index):
+        psuid = '0' if index == 1 else '1'
+        sysfs_path = '/sys/devices/platform/dell-n3248te-cpld.0/psu' + psuid + '_prs'
+        found_psu = int(open(sysfs_path).read())
+        if not found_psu : return ''
+        bus_no = '10' if index == 1 else '11'
+        sysfs_path = "/sys/bus/i2c/devices/" + bus_no + "-0056/eeprom"
+        val = (open(sysfs_path, "rb").read())[0xe1:0xe8]
+        dir = 'F2B' if 'FORWARD' == val else 'B2F'
+        return dir
+
+    def get_serial(self, index):
+        psuid = '0' if index == 1 else '1'
+        sysfs_path = '/sys/devices/platform/dell-n3248te-cpld.0/psu' + psuid + '_prs'
+        found_psu = int(open(sysfs_path).read())
+        if not found_psu : return ''
+        bus_no = '10' if index == 1 else '11'
+        sysfs_path = "/sys/bus/i2c/devices/" + bus_no + "-0056/eeprom"
+        val = (open(sysfs_path, "rb").read())[0xc4:0xd9]
+        return val
+
+    def get_model(self, index):
+        psuid = '0' if index == 1 else '1'
+        sysfs_path = '/sys/devices/platform/dell-n3248te-cpld.0/psu' + psuid + '_prs'
+        found_psu = int(open(sysfs_path).read())
+        if not found_psu : return ''
+        bus_no = '10' if index == 1 else '11'
+        sysfs_path = "/sys/bus/i2c/devices/" + bus_no + "-0056/eeprom"
+        val = (open(sysfs_path, "rb").read())[0x50:0x62]
+        return val
+
+    def get_mfr_id(self, index):
+        psuid = '0' if index == 1 else '1'
+        sysfs_path = '/sys/devices/platform/dell-n3248te-cpld.0/psu' + psuid + '_prs'
+        found_psu = int(open(sysfs_path).read())
+        return 'DELTA' if  found_psu else  ''
diff --git a/device/dell/x86_64-dellemc_n3248te_c3338-r0/plugins/sfputil.py b/device/dell/x86_64-dellemc_n3248te_c3338-r0/plugins/sfputil.py
new file mode 100644
index 000000000000..36df99d97591
--- /dev/null
+++ b/device/dell/x86_64-dellemc_n3248te_c3338-r0/plugins/sfputil.py
@@ -0,0 +1,176 @@
+# sfputil.py
+#
+# Platform-specific SFP transceiver interface for SONiC
+#
+
+try:
+    import time
+    import datetime
+    import os
+    import struct
+    import traceback
+    from socket import *
+    from select import *
+    from sonic_sfp.sfputilbase import SfpUtilBase
+except ImportError as e:
+    raise ImportError("%s - required module not found" % str(e))
+
+class SfpUtil(SfpUtilBase):
+    """Platform-specific SfpUtil class"""
+
+    PORT_START = 1
+    PORT_END = 52
+    PORTS_IN_BLOCK = 52
+    SFP_PORT_START = 49
+    SFP_PORT_END = 52
+
+    EEPROM_OFFSET = 14
+
+    _port_to_eeprom_mapping = {}
+    _sfpp_port_i2c_mapping  = {
+        49 : 20,
+        50 : 21,
+        51 : 22,
+        52 : 23
+    }
+    port_dict = {}
+
+    @property
+    def port_start(self):
+        return self.PORT_START
+
+    @property
+    def port_end(self):
+        return self.PORT_END
+
+    @property
+    def qsfp_ports(self) :
+        return range(self.SFP_PORT_END+1, self.SFP_PORT_END+1)
+
+    @property
+    def port_to_eeprom_mapping(self):
+        return self._port_to_eeprom_mapping
+
+    @property
+    def get_transceiver_status(self):
+
+        try:
+            sfp_modprs_path = "/sys/devices/platform/dell-n3248te-cpld.0/sfp_modprs"
+            reg_file = open(sfp_modprs_path)
+
+        except IOError as e:
+            print ("Error: unable to open file: %s" % str(e))
+            return False
+
+        content = reg_file.readline().rstrip()
+
+        reg_file.close()
+
+        return int(content, 16)
+
+
+    def __init__(self):
+
+        sfpplus_eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom"
+
+        for x in range(self.SFP_PORT_START, self.SFP_PORT_END + 1):
+            self.port_to_eeprom_mapping[x] = sfpplus_eeprom_path.format(self._sfpp_port_i2c_mapping[x])
+        # Get Transceiver status
+        self.modprs_register = self.get_transceiver_status
+
+        SfpUtilBase.__init__(self)
+
+    def get_presence(self, port_num):
+        # Check for invalid port_num
+        if port_num < self.port_start or port_num > self.port_end:
+            return False
+
+        if port_num < self.SFP_PORT_START :
+            return False
+        port_num -= self.SFP_PORT_START
+        try:
+            sfp_modprs_path = "/sys/devices/platform/dell-n3248te-cpld.0/sfp_modprs"
+            reg_file = open(sfp_modprs_path)
+        except IOError as e:
+            print ("Error: unable to open file: %s" % str(e))
+            return False
+
+        content = reg_file.readline().rstrip()
+
+        # content is a string containing the hex representation of the register
+        reg_value = int(content, 16)
+
+        # Mask off the bit corresponding to our port
+        mask = (1 << port_num)
+
+        # ModPrsL is active low
+        if (reg_value & mask) == 0:
+            return True
+
+        return False
+
+    def get_low_power_mode(self, port_num):
+        return False
+
+    def set_low_power_mode(self, port_num, lpmode):
+        return False
+
+    def reset(self, port_num):
+        return False
+
+    def get_transceiver_change_event(self, timeout=0):
+
+        start_time = time.time()
+        port = self.SFP_PORT_START
+        forever = False
+
+        if timeout == 0:
+            forever = True
+        elif timeout > 0:
+            timeout = timeout / float(1000) # Convert to secs
+        else:
+            print ('get_transceiver_change_event:Invalid timeout value', timeout)
+            return False, {}
+
+        end_time = start_time + timeout
+        if start_time > end_time:
+            print ('get_transceiver_change_event:' \
+                       'time wrap / invalid timeout value', timeout)
+
+            return False, {} # Time wrap or possibly incorrect timeout
+
+        while timeout >= 0:
+            # Check for OIR events and return updated port_dict
+            reg_value = self.get_transceiver_status
+            if reg_value != self.modprs_register:
+                changed_ports = self.modprs_register ^ reg_value
+                while port >= self.SFP_PORT_START and port <= self.SFP_PORT_END:
+
+                    # Mask off the bit corresponding to our port
+                    mask = (1 << (port - self.SFP_PORT_START))
+
+                    if changed_ports & mask:
+                        # ModPrsL is active low
+                        if reg_value & mask == 0:
+                            self.port_dict[port] = '1'
+                        else:
+                            self.port_dict[port] = '0'
+
+                    port += 1
+
+                # Update reg value
+                self.modprs_register = reg_value
+                return True, self.port_dict
+
+            if forever:
+                time.sleep(1)
+            else:
+                timeout = end_time - time.time()
+                if timeout >= 1:
+                    time.sleep(1) # We poll at 1 second granularity
+                else:
+                    if timeout > 0:
+                        time.sleep(timeout)
+                    return True, {}
+        print ("get_transceiver_change_event: Should not reach here.")
+        return False, {}
diff --git a/device/dell/x86_64-dellemc_n3248te_c3338-r0/pmon_daemon_control.json b/device/dell/x86_64-dellemc_n3248te_c3338-r0/pmon_daemon_control.json
new file mode 100644
index 000000000000..4f701c3b3400
--- /dev/null
+++ b/device/dell/x86_64-dellemc_n3248te_c3338-r0/pmon_daemon_control.json
@@ -0,0 +1,3 @@
+{
+    "skip_ledd":     true
+}
diff --git a/device/dell/x86_64-dellemc_n3248te_c3338-r0/sensors.conf b/device/dell/x86_64-dellemc_n3248te_c3338-r0/sensors.conf
new file mode 100644
index 000000000000..987b4ad73984
--- /dev/null
+++ b/device/dell/x86_64-dellemc_n3248te_c3338-r0/sensors.conf
@@ -0,0 +1,58 @@
+# libsensors configuration file for Dell N3248TE
+# The i2c bus portion is omit because adapter name
+# changes every time when system boot up.
+
+bus "i2c-7" "i2c-0-mux (chan_id 5)"
+bus "i2c-5" "i2c-0-mux (chan_id 3)"
+bus "i2c-10" "i2c-5-mux (chan_id 0)"
+bus "i2c-11" "i2c-5-mux (chan_id 1)"
+
+chip "tmp75-i2c-7-49"
+        label temp1 "Switch Near Temperature"
+chip "tmp75-i2c-7-4a"
+        label temp1 "Switch Rear Temperature"
+chip "tmp75-i2c-7-4b"
+        label temp1 "Front Panel PHY Temperature"
+chip "tmp75-i2c-7-4c"
+        label temp1 "Near Front Panel Temperature"
+chip "tmp75-i2c-7-4f"
+        label temp1 "Middle Fan Tray Temperature"
+
+
+chip "emc2305-i2c-7-2c"
+        ignore fan4
+        ignore fan5
+        label fan1 "Fan 1 "
+	label fan2 "Fan 2 "
+        label fan3 "Fan 3 "
+
+chip "dps460-i2c-10-5e"
+	label power1 "Input Power"
+	label power2 "Output Power"
+        label curr1 "Input Current"
+	label curr2 "Output Current"
+        label in1 "Input Voltage"
+	ignore in2
+	label in3 "Output Voltage"
+	label fan1 "Fan RPM"
+	ignore fan2
+	ignore fan3
+	ignore temp1
+	label temp2 "FAN Airflow Temperature"
+	label temp3 "FAN Normal Temperature"
+
+
+chip "dps460-i2c-11-5e"
+	label power1 "Input Power"
+	label power2 "Output Power"
+        label curr1 "Input Current"
+	label curr2 "Output Current"
+        label in1 "Input Voltage"
+	ignore in2
+	label in3 "Output Voltage"
+	label fan1 "Fan RPM"
+	ignore fan2
+	ignore fan3
+	ignore temp1
+	label temp2 "FAN Airflow Temperature"
+	label temp3 "FAN Normal Temperature"
diff --git a/platform/broadcom/one-image.mk b/platform/broadcom/one-image.mk
index d11f82bde341..ea25d6262dfc 100644
--- a/platform/broadcom/one-image.mk
+++ b/platform/broadcom/one-image.mk
@@ -15,6 +15,7 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \
                                $(DELL_S5296F_PLATFORM_MODULE) \
                                $(DELL_Z9100_PLATFORM_MODULE) \
                                $(DELL_S6100_PLATFORM_MODULE) \
+                               $(DELL_N3248TE_PLATFORM_MODULE) \
                                $(INGRASYS_S8900_54XC_PLATFORM_MODULE) \
                                $(INGRASYS_S8900_64XC_PLATFORM_MODULE) \
                                $(INGRASYS_S9100_PLATFORM_MODULE) \
diff --git a/platform/broadcom/platform-modules-dell.mk b/platform/broadcom/platform-modules-dell.mk
index 90eb4fc20b5a..4e0363772a6a 100644
--- a/platform/broadcom/platform-modules-dell.mk
+++ b/platform/broadcom/platform-modules-dell.mk
@@ -8,6 +8,7 @@ DELL_S5232F_PLATFORM_MODULE_VERSION = 1.1
 DELL_Z9332F_PLATFORM_MODULE_VERSION = 1.1
 DELL_S5248F_PLATFORM_MODULE_VERSION = 1.1
 DELL_S5296F_PLATFORM_MODULE_VERSION = 1.1
+DELL_N3248TE_PLATFORM_MODULE_VERSION = 1.1
 
 export DELL_S6000_PLATFORM_MODULE_VERSION
 export DELL_Z9100_PLATFORM_MODULE_VERSION
@@ -17,6 +18,7 @@ export DELL_S5232F_PLATFORM_MODULE_VERSION
 export DELL_Z9332F_PLATFORM_MODULE_VERSION
 export DELL_S5248F_PLATFORM_MODULE_VERSION
 export DELL_S5296F_PLATFORM_MODULE_VERSION
+export DELL_N3248TE_PLATFORM_MODULE_VERSION
 
 DELL_Z9100_PLATFORM_MODULE = platform-modules-z9100_$(DELL_Z9100_PLATFORM_MODULE_VERSION)_amd64.deb
 $(DELL_Z9100_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-dell
@@ -49,6 +51,10 @@ DELL_S5248F_PLATFORM_MODULE = platform-modules-s5248f_$(DELL_S5248F_PLATFORM_MOD
 $(DELL_S5248F_PLATFORM_MODULE)_PLATFORM = x86_64-dellemc_s5248f_c3538-r0
 $(eval $(call add_extra_package,$(DELL_Z9100_PLATFORM_MODULE),$(DELL_S5248F_PLATFORM_MODULE)))
 
+DELL_N3248TE_PLATFORM_MODULE = platform-modules-n3248te_$(DELL_N3248TE_PLATFORM_MODULE_VERSION)_amd64.deb
+$(DELL_N3248TE_PLATFORM_MODULE)_PLATFORM = x86_64-dellemc_n3248te_c3338-r0
+$(eval $(call add_extra_package,$(DELL_Z9100_PLATFORM_MODULE),$(DELL_N3248TE_PLATFORM_MODULE)))
+
 DELL_S5296F_PLATFORM_MODULE = platform-modules-s5296f_$(DELL_S5296F_PLATFORM_MODULE_VERSION)_amd64.deb
 $(DELL_S5296F_PLATFORM_MODULE)_PLATFORM = x86_64-dellemc_s5296f_c3538-r0
 $(eval $(call add_extra_package,$(DELL_Z9100_PLATFORM_MODULE),$(DELL_S5296F_PLATFORM_MODULE)))
diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/control b/platform/broadcom/sonic-platform-modules-dell/debian/control
index 2920602fcd60..85585a5cf122 100644
--- a/platform/broadcom/sonic-platform-modules-dell/debian/control
+++ b/platform/broadcom/sonic-platform-modules-dell/debian/control
@@ -35,6 +35,11 @@ Architecture: amd64
 Depends: linux-image-4.19.0-12-2-amd64-unsigned
 Description: kernel modules for platform devices such as fan, led, sfp
 
+Package: platform-modules-n3248te
+Architecture: amd64
+Depends: linux-image-4.19.0-12-2-amd64-unsigned
+Description: kernel modules for platform devices such as fan, led, sfp
+
 Package: platform-modules-z9332f
 Architecture: amd64
 Depends: linux-image-4.19.0-12-2-amd64-unsigned
diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-n3248te.init b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-n3248te.init
new file mode 100755
index 000000000000..823e0708e8f8
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-n3248te.init
@@ -0,0 +1,39 @@
+#!/bin/bash
+
+### BEGIN INIT INFO
+# Provides:          setup-board
+# Required-Start:
+# Required-Stop:
+# Should-Start:
+# Should-Stop:
+# Default-Start:     S
+# Default-Stop:      0 6
+# Short-Description: Setup S3000 board.
+### END INIT INFO
+
+case "$1" in
+start)
+    echo -n "Setting up board... "
+
+    /usr/local/bin/n3248te_platform.sh init
+
+    echo "done."
+    ;;
+
+stop)
+    /usr/local/bin/n3248te_platform.sh deinit
+    echo "done."
+
+    ;;
+
+force-reload|restart)
+    echo "Not supported"
+    ;;
+
+*)
+    echo "Usage: /etc/init.d/platform-modules-n3248te.init {start|stop}"
+    exit 1
+    ;;
+esac
+
+exit 0
diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-n3248te.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-n3248te.install
new file mode 100644
index 000000000000..04fe8c5a337e
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-n3248te.install
@@ -0,0 +1,12 @@
+n3248te/scripts/n3248te_platform.sh usr/local/bin
+n3248te/scripts/platform_sensors.py usr/local/bin
+n3248te/scripts/sensors usr/bin
+n3248te/scripts//portiocfg.py usr/local/bin
+n3248te/scripts//ports_xcvrd_notify.py usr/local/bin
+n3248te/systemd/platform-modules-n3248te.service etc/systemd/system
+n3248te/cfg/n3248te-modules.conf etc/modules-load.d
+common/dell_i2c_utils.sh usr/local/bin
+n3248te/modules/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/x86_64-dellemc_n3248te_c3338-r0
+common/platform_reboot usr/share/sonic/device/x86_64-dellemc_n3248te_c3338-r0
+common/fw-updater /usr/local/bin
+common/onie_mode_set usr/local/bin
diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-n3248te.postinst b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-n3248te.postinst
new file mode 100644
index 000000000000..7f787c2a328c
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-n3248te.postinst
@@ -0,0 +1,7 @@
+# postinst script for N3248TE
+
+# Enable Dell-N3248TE-platform-service
+depmod -a
+systemctl enable platform-modules-n3248te.service
+systemctl start platform-modules-n3248te.service
+#DEBHELPER#
diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/rules b/platform/broadcom/sonic-platform-modules-dell/debian/rules
index 520331ed16d3..5bc62aba0891 100755
--- a/platform/broadcom/sonic-platform-modules-dell/debian/rules
+++ b/platform/broadcom/sonic-platform-modules-dell/debian/rules
@@ -5,7 +5,7 @@ export INSTALL_MOD_DIR:=extra
 KVERSION   ?= $(shell uname -r)
 KERNEL_SRC :=  /lib/modules/$(KVERSION)
 MOD_SRC_DIR:= $(shell pwd)
-MODULE_DIRS:= s6000 z9100 s6100 z9264f s5232f s5248f z9332f s5296f 
+MODULE_DIRS:= s6000 z9100 s6100 z9264f s5232f s5248f z9332f s5296f n3248te
 COMMON_DIR := common
 
 %:
@@ -50,6 +50,11 @@ override_dh_auto_build:
 			cd $(MOD_SRC_DIR)/$${mod}; \
 			python3 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \
 			cd $(MOD_SRC_DIR); \
+		elif [ $$mod = "n3248te" ]; then \
+			cp $(COMMON_DIR)/ipmihelper.py $(MOD_SRC_DIR)/$${mod}/sonic_platform/ipmihelper.py; \
+			cd $(MOD_SRC_DIR)/$${mod}; \
+			python3 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \
+			cd $(MOD_SRC_DIR); \
 		elif [ $$mod = "z9332f" ]; then \
 			cp $(COMMON_DIR)/ipmihelper.py $(MOD_SRC_DIR)/$${mod}/sonic_platform/ipmihelper.py; \
 			cd $(MOD_SRC_DIR)/$${mod}; \
@@ -118,6 +123,11 @@ override_dh_clean:
 			rm -f $(MOD_SRC_DIR)/$${mod}/modules/*.whl; \
 			rm -rf $(MOD_SRC_DIR)/$${mod}/build; \
 			rm -rf $(MOD_SRC_DIR)/$${mod}/build/*.egg-info; \
+		elif [ $$mod = "n3248te" ]; then \
+			rm -f $(MOD_SRC_DIR)/$${mod}/sonic_platform/ipmihelper.py; \
+			rm -f $(MOD_SRC_DIR)/$${mod}/modules/*.whl; \
+			rm -rf $(MOD_SRC_DIR)/$${mod}/build; \
+			rm -rf $(MOD_SRC_DIR)/$${mod}/build/*.egg-info; \
 		fi; \
 		make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules clean; \
 	done); \
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/cfg/n3248te-modules.conf b/platform/broadcom/sonic-platform-modules-dell/n3248te/cfg/n3248te-modules.conf
new file mode 100644
index 000000000000..923b364b375e
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/cfg/n3248te-modules.conf
@@ -0,0 +1,14 @@
+# /etc/modules: kernel modules to load at boot time.
+#
+# This file contains the names of kernel modules that should be loaded
+# at boot time, one per line. Lines beginning with "#" are ignored.
+
+i2c-isch
+i2c-ismt
+i2c-dev
+i2c-mux
+i2c-smbus
+
+i2c-mux-pca954x
+dell_n3248te_platform
+
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/modules/Makefile b/platform/broadcom/sonic-platform-modules-dell/n3248te/modules/Makefile
new file mode 100644
index 000000000000..2ce4d5b5e963
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/modules/Makefile
@@ -0,0 +1,2 @@
+obj-m := dell_n3248te_platform.o emc2305.o
+
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/modules/dell_n3248te_platform.c b/platform/broadcom/sonic-platform-modules-dell/n3248te/modules/dell_n3248te_platform.c
new file mode 100644
index 000000000000..aa6a6672b552
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/modules/dell_n3248te_platform.c
@@ -0,0 +1,1236 @@
+/* Copyright (c) 2020 Dell Inc.
+ * dell_n3248te_platform.c - Driver for N3248TE switches
+ *
+ * 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 <linux/module.h>
+    #include <linux/kernel.h>
+    #include <linux/sysfs.h>
+    #include <linux/slab.h>
+    #include <linux/stat.h>
+    #include <linux/i2c.h>
+    #include <linux/i2c-mux.h>
+    #include <linux/platform_device.h>
+    #include <linux/i2c/sff-8436.h>
+    #include <linux/delay.h>
+    #include <linux/hwmon-sysfs.h>
+
+    #define PSU_MODULE_BASE_NR      10
+    #define FANTRAY_MODULE_BASE_NR  15
+    #define SFP_MODULE_BASE_NR      20
+    #define SFP_MUX_BASE_NR         8
+    #define FANTRAY_MUX_BASE_NR     4
+    #define PSU_MUX_BASE_NR         5
+
+    #define PHY_RESET_REG           0x40
+    #define RESET_ALL_PHY           0x7F
+    #define SYS_CTRL_REG            0x15
+    #define POWER_CYCLE_SYS         0x1
+    #define CPLD_DEVICE_NUM         2
+    #define PF_MUX_DEVICES          3
+
+    #define FAN_0                   0
+    #define FAN_1                   1
+    #define FAN_2                   2
+
+    static void device_release(struct device *dev)
+    {
+        return;
+    }
+
+    /*
+     * N3248TE CPLD
+     */
+
+    enum cpld_type {
+        cpu_cpld,
+        sys_cpld,
+    };
+
+    struct cpld_platform_data {
+        int reg_addr;
+        struct i2c_client *client;
+    };
+
+    static struct cpld_platform_data n3248te_cpld_platform_data[] = {
+        [cpu_cpld] = {
+            .reg_addr = 0x31,
+        },
+
+        [sys_cpld] = {
+            .reg_addr = 0x32,
+        },
+    };
+
+    static struct platform_device n3248te_cpld = {
+        .name               = "dell-n3248te-cpld",
+        .id                 = 0,
+        .dev                = {
+                    .platform_data   = n3248te_cpld_platform_data,
+                    .release         = device_release
+        },
+    };
+
+    /*
+     * N3248TE MUX
+     */
+
+    struct mux_platform_data {
+        int parent;
+        int base_nr;
+        int reg_addr;
+        struct i2c_client *cpld;
+        int no_of_buses;
+        int mux_offset;
+    };
+
+    struct pf_mux {
+        struct mux_platform_data data;
+    };
+
+    static struct mux_platform_data n3248te_mux_platform_data[] = {
+        {
+            .parent         = SFP_MUX_BASE_NR,
+            .base_nr        = SFP_MODULE_BASE_NR,
+            .cpld           = NULL,
+            .reg_addr       = 0x11,
+            .no_of_buses    = 6,
+            .mux_offset     = 1,
+        },
+        {
+            .parent         = FANTRAY_MUX_BASE_NR,
+            .base_nr        = FANTRAY_MODULE_BASE_NR,
+            .cpld           = NULL,
+            .reg_addr       = 0x13,
+            .no_of_buses    = 3,
+            .mux_offset     = 1,
+        },
+        {
+            .parent         = PSU_MUX_BASE_NR,
+            .base_nr        = PSU_MODULE_BASE_NR,
+            .cpld           = NULL,
+            .reg_addr       = 0x12,
+            .no_of_buses    = 2,
+            .mux_offset     = 1,
+        },
+    };
+
+    static struct platform_device n3248te_mux[] = {
+        {
+            .name           = "dell-n3248te-mux",
+            .id             = 0,
+            .dev            = {
+                    .platform_data   = &n3248te_mux_platform_data[0],
+                    .release         = device_release,
+            },
+        },
+        {
+            .name           = "dell-n3248te-mux",
+            .id             = 1,
+            .dev            = {
+                    .platform_data   = &n3248te_mux_platform_data[1],
+                    .release         = device_release,
+            },
+        },
+        {
+            .name           = "dell-n3248te-mux",
+            .id             = 2,
+            .dev            = {
+                    .platform_data   = &n3248te_mux_platform_data[2],
+                    .release         = device_release,
+            },
+        },
+    };
+
+    static int cpld_reg_write_byte(struct i2c_client *client, u8 regaddr, u8 val)
+    {
+        union i2c_smbus_data data;
+
+        data.byte = val;
+        return client->adapter->algo->smbus_xfer(client->adapter, client->addr,
+                                             client->flags,
+                                             I2C_SMBUS_WRITE,
+                                             regaddr, I2C_SMBUS_BYTE_DATA, &data);
+    }
+
+    static int mux_select(struct i2c_mux_core *muxc, u32 chan)
+    {
+        struct pf_mux *mux = i2c_mux_priv(muxc);
+        u8 chan_data = chan + mux->data.mux_offset;
+
+        return cpld_reg_write_byte(mux->data.cpld, mux->data.reg_addr, chan_data);
+    }
+
+    static int __init mux_probe(struct platform_device *pdev)
+    {
+        struct i2c_mux_core *muxc;
+        struct pf_mux *mux;
+        struct mux_platform_data *pdata;
+        struct i2c_adapter *parent;
+        int i, ret;
+
+        pdata = pdev->dev.platform_data;
+        if (!pdata) {
+            dev_err(&pdev->dev, "Missing platform data\n");
+            return -ENODEV;
+        }
+
+        mux = devm_kzalloc(&pdev->dev, sizeof(*mux), GFP_KERNEL);
+        if (!mux) {
+            return -ENOMEM;
+        }
+
+        mux->data = *pdata;
+
+        parent = i2c_get_adapter(pdata->parent);
+        if (!parent) {
+            dev_err(&pdev->dev, "Parent adapter (%d) not found\n",
+                pdata->parent);
+            return -EPROBE_DEFER;
+        }
+
+        muxc = i2c_mux_alloc(parent, &pdev->dev, pdata->no_of_buses, 0, 0,
+                             mux_select, NULL);
+        if (!muxc) {
+            ret = -ENOMEM;
+            goto alloc_failed;
+        }
+        muxc->priv = mux;
+
+        platform_set_drvdata(pdev, muxc);
+
+        for (i = 0; i < pdata->no_of_buses; i++) {
+            int nr = pdata->base_nr + i;
+            unsigned int class = 0;
+
+            ret = i2c_mux_add_adapter(muxc, nr, i, class);
+            if (ret) {
+                dev_err(&pdev->dev, "Failed to add adapter %d\n", i);
+                goto add_adapter_failed;
+            }
+        }
+
+        return 0;
+
+    add_adapter_failed:
+        i2c_mux_del_adapters(muxc);
+    alloc_failed:
+        i2c_put_adapter(parent);
+
+        return ret;
+    }
+
+    static int mux_remove(struct platform_device *pdev)
+    {
+        struct i2c_mux_core *muxc = platform_get_drvdata(pdev);
+
+        i2c_mux_del_adapters(muxc);
+
+        i2c_put_adapter(muxc->parent);
+
+        return 0;
+    }
+
+    static struct platform_driver mux_driver = {
+        .probe  = mux_probe,
+        .remove = mux_remove,
+        .driver = {
+            .owner  = THIS_MODULE,
+            .name   = "dell-n3248te-mux",
+        },
+    };
+
+    static ssize_t sfp_txdis_show (struct device *dev, struct device_attribute *devattr, char *buf)
+    {
+        s32 ret = 0;
+        struct cpld_platform_data *pdata = dev->platform_data;
+
+        ret = i2c_smbus_read_byte_data(pdata[sys_cpld].client, 0x31);
+        if (ret < 0)
+            return sprintf(buf, "read error");
+
+        return sprintf(buf, "0x%x\n", (u8)ret);
+    }
+
+    static ssize_t sfp_txdis_store (struct device *dev, struct device_attribute *devattr, const char *buf, size_t size)
+    {
+        long value;
+        struct cpld_platform_data *pdata = dev->platform_data;
+        s32 ret;
+        u8 data;
+        ssize_t status;
+
+        status = kstrtol(buf, 0, &value);
+        if (status == 0) {
+            ret = i2c_smbus_read_byte_data(pdata[sys_cpld].client, 0x31);
+            if (ret < 0)
+                return ret;
+            data = (u8)ret & ~(0x0F);
+            data = data | (value & 0x0F);
+
+            ret = i2c_smbus_write_byte_data(pdata[sys_cpld].client, 0x31, data);
+            if (ret < 0)
+                return ret;
+
+            status = size;
+        }
+
+        return status;
+    }
+
+    static ssize_t sfp_rxlos_show (struct device *dev, struct device_attribute *devattr, char *buf)
+    {
+        s32 ret = 0;
+        struct cpld_platform_data *pdata = dev->platform_data;
+
+        ret = i2c_smbus_read_byte_data(pdata[sys_cpld].client, 0x32);
+        if (ret < 0)
+            return sprintf(buf, "read error");
+
+        return sprintf(buf, "0x%x\n", (u8)ret);
+    }
+
+    static ssize_t sfp_txfault_show (struct device *dev, struct device_attribute *devattr, char *buf)
+    {
+        s32 ret = 0;
+        struct cpld_platform_data *pdata = dev->platform_data;
+
+        ret = i2c_smbus_read_byte_data(pdata[sys_cpld].client, 0x33);
+        if (ret < 0)
+            return sprintf(buf, "read error");
+
+        return sprintf(buf, "0x%x\n", (u8)ret);
+    }
+
+    static ssize_t sfp_modprs_show (struct device *dev, struct device_attribute *devattr, char *buf)
+    {
+        s32 ret = 0;
+        struct cpld_platform_data *pdata = dev->platform_data;
+
+        ret = i2c_smbus_read_byte_data(pdata[sys_cpld].client, 0x30);
+        if (ret < 0)
+            return sprintf(buf, "read error");
+
+        return sprintf(buf, "0x%x\n", (u8)ret);
+    }
+
+    static ssize_t qsfp_modprs_show (struct device *dev, struct device_attribute *devattr, char *buf)
+    {
+        s32 ret = 0;
+        struct cpld_platform_data *pdata = dev->platform_data;
+
+        ret = i2c_smbus_read_byte_data(pdata[sys_cpld].client, 0x20);
+        if (ret < 0)
+            return sprintf(buf, "read error");
+
+        return sprintf(buf, "0x%x\n", (u8)ret);
+    }
+
+    static ssize_t qsfp_rst_show (struct device *dev, struct device_attribute *devattr, char *buf)
+    {
+        s32 ret = 0;
+        struct cpld_platform_data *pdata = dev->platform_data;
+
+        ret = i2c_smbus_read_byte_data(pdata[sys_cpld].client, 0x21);
+        if (ret < 0)
+            return sprintf(buf, "read error");
+
+        return sprintf(buf, "0x%x\n", (u8)ret);
+    }
+
+    static ssize_t reboot_cause_show (struct device *dev, struct device_attribute *devattr, char *buf)
+    {
+        s32 ret = 0;
+        u8 data;
+        struct cpld_platform_data *pdata = dev->platform_data;
+
+        ret = i2c_smbus_read_byte_data(pdata[sys_cpld].client, 0x10);
+        if (ret < 0)
+            return sprintf(buf, "read error");
+
+        data = (u8)ret;
+        return sprintf(buf, "0x%x\n", data);
+    }
+
+
+    static ssize_t power_reset_store(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count)
+    {
+        unsigned long data;
+        s32 err;
+        struct cpld_platform_data *pdata = dev->platform_data;
+
+        err = kstrtoul(buf, 10, &data);
+        if (err)
+            return err;
+
+        if (data)
+        {
+            i2c_smbus_write_byte_data(pdata[sys_cpld].client, SYS_CTRL_REG, (u8)(POWER_CYCLE_SYS));
+        }
+
+        return count;
+    }
+
+    static ssize_t power_reset_show(struct device *dev, struct device_attribute *devattr, char *buf)
+    {
+        s32 ret = 0;
+        struct cpld_platform_data *pdata = dev->platform_data;
+
+        ret = i2c_smbus_read_byte_data(pdata[sys_cpld].client, SYS_CTRL_REG);
+        if (ret < 0)
+            return sprintf(buf, "read error");
+
+        return sprintf(buf, "0x%x\n", ret);
+    }
+
+    static ssize_t fan_dir_show(struct device *dev, struct device_attribute *devattr, char *buf)
+    {
+        s32 ret;
+        u8 data = 0;
+        struct cpld_platform_data *pdata = dev->platform_data;
+        struct sensor_device_attribute *sa = to_sensor_dev_attr(devattr);
+    int index = sa->index;
+    u8 mask = 1 << (index+4);
+
+    ret = i2c_smbus_read_byte_data(pdata[sys_cpld].client, 0xA);
+    if (ret < 0)
+        return sprintf(buf, "read error");
+    data = (u8)((ret & mask) >> (index+4));
+
+    return sprintf(buf, "%s\n", data? "B2F" : "F2B");
+}
+
+static ssize_t fan_prs_show(struct device *dev, struct device_attribute *devattr, char *buf)
+{
+    s32 ret;
+    u8 data = 0;
+    struct cpld_platform_data *pdata = dev->platform_data;
+    struct sensor_device_attribute *sa = to_sensor_dev_attr(devattr);
+    int index = sa->index;
+    uint8_t mask = 1 << index;
+
+    ret = i2c_smbus_read_byte_data(pdata[sys_cpld].client, 0xA);
+    if (ret < 0)
+        return sprintf(buf, "read error");
+    data = (u32)((ret & mask) >> index);
+
+    data = ~data & 0x1;
+
+    return sprintf(buf, "0x%x\n", data);
+}
+
+static ssize_t psu0_prs_show(struct device *dev, struct device_attribute *devattr, char *buf)
+{
+    s32 ret;
+    u8 data = 0;
+    struct cpld_platform_data *pdata = dev->platform_data;
+
+    ret = i2c_smbus_read_byte_data(pdata[sys_cpld].client, 0xC);
+    if (ret < 0)
+        return sprintf(buf, "read error");
+
+    if (!(ret & 0x80))
+        data = 1;
+
+    return sprintf(buf, "%d\n", data);
+}
+
+static ssize_t psu1_prs_show(struct device *dev, struct device_attribute *devattr, char *buf)
+{
+    s32 ret;
+    u8 data = 0;
+    struct cpld_platform_data *pdata = dev->platform_data;
+
+    ret = i2c_smbus_read_byte_data(pdata[sys_cpld].client, 0xC);
+    if (ret < 0)
+        return sprintf(buf, "read error");
+
+    if (!(ret & 0x08))
+        data = 1;
+
+    return sprintf(buf, "%d\n", data);
+}
+
+static ssize_t psu0_status_show(struct device *dev, struct device_attribute *devattr, char *buf)
+{
+    s32 ret;
+    u8 data = 0;
+    struct cpld_platform_data *pdata = dev->platform_data;
+
+    ret = i2c_smbus_read_byte_data(pdata[sys_cpld].client, 0xC);
+    if (ret < 0)
+        return sprintf(buf, "read error");
+
+    if ((ret & 0x40))
+        data = 1;
+
+    return sprintf(buf, "%d\n", data);
+}
+
+static ssize_t psu1_status_show(struct device *dev, struct device_attribute *devattr, char *buf)
+{
+    s32 ret;
+    u8 data = 0;
+    struct cpld_platform_data *pdata = dev->platform_data;
+
+    ret = i2c_smbus_read_byte_data(pdata[sys_cpld].client, 0xC);
+    if (ret < 0)
+        return sprintf(buf, "read error");
+
+    if ((ret & 0x04))
+        data = 1;
+
+    return sprintf(buf, "%d\n", data);
+}
+
+static ssize_t fani_led_show(struct device *dev, struct device_attribute *devattr, char *buf)
+{
+    s32 ret;
+    u8 data = 0;
+    struct cpld_platform_data *pdata = dev->platform_data;
+    struct sensor_device_attribute *sa = to_sensor_dev_attr(devattr);
+    int index = sa->index;
+    uint8_t mask = 3 << (index*2);
+
+    ret = i2c_smbus_read_byte_data(pdata[sys_cpld].client, 0x9);
+    if (ret < 0)
+        return sprintf(buf, "read error");
+
+    data = (u32)(ret & mask) >> (index*2);
+
+    switch (data)
+    {
+        case 0:
+            ret = sprintf(buf, "off\n");
+            break;
+        case 1:
+            ret = sprintf(buf, "green\n");
+            break;
+        case 2:
+            ret = sprintf(buf, "yellow\n");
+            break;
+        default:
+            ret = sprintf(buf, "unknown\n");
+    }
+
+    return ret;
+}
+
+static ssize_t fani_led_store(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count)
+{
+    s32 ret;
+    u8 mask, data = 0;
+    struct cpld_platform_data *pdata = dev->platform_data;
+    struct sensor_device_attribute *sa = to_sensor_dev_attr(devattr);
+    int index = sa->index;
+
+    if (!strncmp(buf, "off", 3))
+    {
+        data = 0;
+    }
+    else if (!strncmp(buf, "yellow", 6))
+    {
+        data = 2;
+    }
+    else if (!strncmp(buf, "green", 5))
+    {
+        data = 1;
+    }
+    else
+    {
+        return -1;
+    }
+
+
+    mask = ~((uint8_t)(3 << (index*2)));
+    ret = i2c_smbus_read_byte_data(pdata[sys_cpld].client, 0x9);
+    if (ret < 0)
+        return ret;
+
+    ret = i2c_smbus_write_byte_data(pdata[sys_cpld].client, 0x9, (u8)((ret & mask) | (data << (index * 2))));
+    if (ret < 0)
+        return ret;
+
+    return count;
+}
+
+static ssize_t system_led_show(struct device *dev, struct device_attribute *devattr, char *buf)
+{
+    s32 ret;
+    u8 data = 0;
+    struct cpld_platform_data *pdata = dev->platform_data;
+
+    ret = i2c_smbus_read_byte_data(pdata[sys_cpld].client, 0x7);
+    if (ret < 0)
+        return sprintf(buf, "read error");
+
+    data = (u8)(ret & 0x30) >> 5;
+
+    switch (data)
+    {
+        case 0:
+            ret = sprintf(buf, "blink_green\n");
+            break;
+        case 1:
+            ret = sprintf(buf, "green\n");
+            break;
+        case 2:
+            ret = sprintf(buf, "yellow\n");
+            break;
+        default:
+            ret = sprintf(buf, "blink_yellow\n");
+    }
+
+    return ret;
+}
+
+static ssize_t system_led_store(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count)
+{
+    s32 ret;
+    u8 data = 0;
+    struct cpld_platform_data *pdata = dev->platform_data;
+
+    if (!strncmp(buf, "blink_green", 11))
+    {
+        data = 0;
+    }
+    else if (!strncmp(buf, "green", 5))
+    {
+        data = 1;
+    }
+    else if (!strncmp(buf, "yellow", 6))
+    {
+        data = 2;
+    }
+    else if (!strncmp(buf, "blink_yellow", 12))
+    {
+        data = 3;
+    }
+    else
+    {
+        return -1;
+    }
+
+    ret = i2c_smbus_read_byte_data(pdata[sys_cpld].client, 0x7);
+    if (ret < 0)
+        return ret;
+
+    ret = i2c_smbus_write_byte_data(pdata[sys_cpld].client, 0x7, (u8)((ret & 0xCF) | (data << 4)));
+    if (ret < 0)
+        return ret;
+
+    return count;
+}
+
+static ssize_t locator_led_show(struct device *dev, struct device_attribute *devattr, char *buf)
+{
+    s32 ret;
+    u8 data = 0;
+    struct cpld_platform_data *pdata = dev->platform_data;
+
+    ret = i2c_smbus_read_byte_data(pdata[sys_cpld].client, 0x7);
+    if (ret < 0)
+        return sprintf(buf, "read error");
+
+    data = (u32)(ret & 0x08) >> 3;
+
+    switch (data)
+    {
+        case 0:
+            ret = sprintf(buf, "off\n");
+            break;
+        case 1:
+            ret = sprintf(buf, "blink_blue\n");
+            break;
+        default:
+            ret = sprintf(buf, "invalid\n");
+    }
+
+    return ret;
+}
+
+static ssize_t locator_led_store(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count)
+{
+    s32 ret;
+    u8 data = 0;
+    struct cpld_platform_data *pdata = dev->platform_data;
+
+    if (!strncmp(buf, "off", 3))
+    {
+        data = 0;
+    }
+    else if (!strncmp(buf, "blink_blue", 10))
+    {
+        data = 1;
+    }
+    else
+    {
+        return -1;
+    }
+
+    ret = i2c_smbus_read_byte_data(pdata[sys_cpld].client, 0x7);
+    if (ret < 0)
+        return ret;
+
+    ret = i2c_smbus_write_byte_data(pdata[sys_cpld].client, 0x7, (u8)((ret & 0xF7) | (data << 3)));
+    if (ret < 0)
+        return ret;
+
+    return count;
+}
+
+static ssize_t power_led_show(struct device *dev, struct device_attribute *devattr, char *buf)
+{
+    s32 ret;
+    u8 data = 0;
+    struct cpld_platform_data *pdata = dev->platform_data;
+
+    ret = i2c_smbus_read_byte_data(pdata[sys_cpld].client, 0x7);
+    if (ret < 0)
+        return sprintf(buf, "read error");
+
+    data = (u32)(ret & 0x06) >> 1;
+
+    switch (data)
+    {
+        case 0:
+            ret = sprintf(buf, "off\n");
+            break;
+        case 1:
+            ret = sprintf(buf, "yellow\n");
+            break;
+        case 2:
+            ret = sprintf(buf, "green\n");
+            break;
+        default:
+            ret = sprintf(buf, "blink_yellow\n");
+    }
+
+    return ret;
+}
+
+static ssize_t power_led_store(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count)
+{
+    s32 ret;
+    u8 data = 0;
+    struct cpld_platform_data *pdata = dev->platform_data;
+
+    if (!strncmp(buf, "off", 3))
+    {
+        data = 0;
+    }
+    else if (!strncmp(buf, "yellow", 6))
+    {
+        data = 1;
+    }
+    else if (!strncmp(buf, "green", 5))
+    {
+        data = 2;
+    }
+    else if (!strncmp(buf, "blink_yellow", 12))
+    {
+        data = 3;
+    }
+    else
+    {
+        return -1;
+    }
+
+    ret = i2c_smbus_read_byte_data(pdata[sys_cpld].client, 0x7);
+    if (ret < 0)
+        return ret;
+
+    ret = i2c_smbus_write_byte_data(pdata[sys_cpld].client, 0x7, (u8)((ret & 0xF9) | (data << 1)));
+    if (ret < 0)
+        return ret;
+
+    return count;
+}
+
+static ssize_t master_led_show(struct device *dev, struct device_attribute *devattr, char *buf)
+{
+    s32 ret;
+    u8 data = 0;
+    struct cpld_platform_data *pdata = dev->platform_data;
+
+    ret = i2c_smbus_read_byte_data(pdata[sys_cpld].client, 0x7);
+    if (ret < 0)
+        return sprintf(buf, "read error");
+
+    data = (u32)(ret & 0x1);
+
+    switch (data)
+    {
+        case 0:
+            ret = sprintf(buf, "green\n");
+            break;
+        default:
+            ret = sprintf(buf, "off\n");
+            break;
+    }
+
+    return ret;
+}
+
+static ssize_t master_led_store(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count)
+{
+    s32 ret;
+    u8 data = 0;
+    struct cpld_platform_data *pdata = dev->platform_data;
+
+    if (!strncmp(buf, "green", 5))
+    {
+        data = 0;
+    }
+    else if (!strncmp(buf, "off", 3))
+    {
+        data = 1;
+    }
+    else
+    {
+        return -1;
+    }
+
+    ret = i2c_smbus_read_byte_data(pdata[sys_cpld].client, 0x7);
+    if (ret < 0)
+        return ret;
+
+    ret = i2c_smbus_write_byte_data(pdata[sys_cpld].client, 0x7, (u8)((ret & 0xFE) | data));
+    if (ret < 0)
+        return ret;
+
+    return count;
+}
+
+static ssize_t fan_led_show(struct device *dev, struct device_attribute *devattr, char *buf)
+{
+    s32 ret;
+    u8 data = 0;
+    struct cpld_platform_data *pdata = dev->platform_data;
+
+    ret = i2c_smbus_read_byte_data(pdata[sys_cpld].client, 0x7);
+    if (ret < 0)
+        return sprintf(buf, "read error");
+
+    data = (u8)(ret & 0xC0) >> 6;
+
+    switch (data)
+    {
+        case 0:
+            ret = sprintf(buf, "off\n");
+            break;
+        case 1:
+            ret = sprintf(buf, "yellow\n");
+            break;
+        case 2:
+            ret = sprintf(buf, "green\n");
+            break;
+        default:
+            ret = sprintf(buf, "blink_yellow\n");
+    }
+
+    return ret;
+}
+
+static ssize_t fan_led_store(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count)
+{
+    s32 ret;
+    u8 data = 0;
+    struct cpld_platform_data *pdata = dev->platform_data;
+
+    if (!strncmp(buf, "off", 3))
+    {
+        data = 0;
+    }
+    else if (!strncmp(buf, "yellow", 6))
+    {
+        data = 1;
+    }
+    else if (!strncmp(buf, "green", 5))
+    {
+        data = 2;
+    }
+    else if (!strncmp(buf, "blink_yellow", 12))
+    {
+        data = 3;
+    }
+    else
+    {
+        return -1;
+    }
+
+    ret = i2c_smbus_read_byte_data(pdata[sys_cpld].client, 0x7);
+    if (ret < 0)
+        return ret;
+
+    ret = i2c_smbus_write_byte_data(pdata[sys_cpld].client, 0x7, (u8)((ret & 0x3F) | (data << 6)));
+    if (ret < 0)
+        return ret;
+
+    return count;
+}
+
+
+static ssize_t power_good_show(struct device *dev,
+                                   struct device_attribute *devattr, char *buf)
+{
+    s32 ret;
+    u8 pwr_good1 = 0;
+    u8 pwr_good2 = 0;
+    struct cpld_platform_data *pdata = dev->platform_data;
+
+    ret = i2c_smbus_read_byte_data(pdata[cpu_cpld].client, 0xc);
+    if (ret < 0)
+        return sprintf(buf, "read error");
+    pwr_good1 = ret;
+
+    ret = i2c_smbus_read_byte_data(pdata[cpu_cpld].client, 0xd);
+    if (ret < 0)
+        return sprintf(buf, "read error");
+    pwr_good2 = ret;
+
+    return sprintf(buf, "0x%x\n", (pwr_good1 == 0xFF &&  (pwr_good2 & 0x1F) == 0x1F));
+}
+
+static ssize_t sys_cpld_mjr_ver_show(struct device *dev,
+                                   struct device_attribute *devattr, char *buf)
+{
+    s32 ret;
+    u8 data = 0;
+    struct cpld_platform_data *pdata = dev->platform_data;
+
+    ret = i2c_smbus_read_byte_data(pdata[sys_cpld].client, 0x1);
+    if (ret < 0)
+        return sprintf(buf, "read error");
+    data = ret;
+
+    return sprintf(buf, "0x%x\n", data);
+}
+
+static ssize_t sys_cpld_mnr_ver_show(struct device *dev,
+                                   struct device_attribute *devattr, char *buf)
+{
+    s32 ret;
+    u8 data = 0;
+    struct cpld_platform_data *pdata = dev->platform_data;
+
+    ret = i2c_smbus_read_byte_data(pdata[sys_cpld].client, 0x0);
+    if (ret < 0)
+        return sprintf(buf, "read error");
+    data = ret;
+
+    return sprintf(buf, "0x%x\n", data);
+}
+
+static ssize_t cpu_cpld_mjr_ver_show(struct device *dev,
+                                   struct device_attribute *devattr, char *buf)
+{
+    s32 ret;
+    u8 data = 0;
+    struct cpld_platform_data *pdata = dev->platform_data;
+
+    ret = i2c_smbus_read_byte_data(pdata[cpu_cpld].client, 0x1);
+    if (ret < 0)
+        return sprintf(buf, "read error");
+    data = ret;
+
+    return sprintf(buf, "0x%x\n", data);
+}
+
+static ssize_t cpu_cpld_mnr_ver_show(struct device *dev,
+                                   struct device_attribute *devattr, char *buf)
+{
+    s32 ret;
+    u8 data = 0;
+    struct cpld_platform_data *pdata = dev->platform_data;
+
+    ret = i2c_smbus_read_byte_data(pdata[cpu_cpld].client, 0x0);
+    if (ret < 0)
+        return sprintf(buf, "read error");
+    data = ret;
+
+    return sprintf(buf, "0x%x\n", data);
+}
+
+
+static DEVICE_ATTR_RO(sfp_txfault);
+static DEVICE_ATTR_RO(sfp_modprs);
+static DEVICE_ATTR_RO(qsfp_modprs);
+static DEVICE_ATTR_RO(qsfp_rst);
+static DEVICE_ATTR_RO(sfp_rxlos);
+static DEVICE_ATTR_RW(sfp_txdis);
+static DEVICE_ATTR_RO(reboot_cause);
+static DEVICE_ATTR_RW(power_reset);
+static DEVICE_ATTR_RO(psu0_prs);
+static DEVICE_ATTR_RO(psu1_prs);
+static DEVICE_ATTR_RO(psu0_status);
+static DEVICE_ATTR_RO(psu1_status);
+static DEVICE_ATTR_RW(system_led);
+static DEVICE_ATTR_RW(locator_led);
+static DEVICE_ATTR_RW(power_led);
+static DEVICE_ATTR_RW(master_led);
+static DEVICE_ATTR_RW(fan_led);
+static DEVICE_ATTR_RO(power_good);
+static DEVICE_ATTR_RO(sys_cpld_mjr_ver);
+static DEVICE_ATTR_RO(sys_cpld_mnr_ver);
+static DEVICE_ATTR_RO(cpu_cpld_mjr_ver);
+static DEVICE_ATTR_RO(cpu_cpld_mnr_ver);
+
+static SENSOR_DEVICE_ATTR(fan0_dir, S_IRUGO, fan_dir_show, NULL, FAN_0);
+static SENSOR_DEVICE_ATTR(fan1_dir, S_IRUGO, fan_dir_show, NULL, FAN_1);
+static SENSOR_DEVICE_ATTR(fan2_dir, S_IRUGO, fan_dir_show, NULL, FAN_2);
+static SENSOR_DEVICE_ATTR(fan0_prs, S_IRUGO, fan_prs_show, NULL, FAN_0);
+static SENSOR_DEVICE_ATTR(fan1_prs, S_IRUGO, fan_prs_show, NULL, FAN_1);
+static SENSOR_DEVICE_ATTR(fan2_prs, S_IRUGO, fan_prs_show, NULL, FAN_2);
+static SENSOR_DEVICE_ATTR(fan0_led, S_IRUGO, fani_led_show, fani_led_store, FAN_0);
+static SENSOR_DEVICE_ATTR(fan1_led, S_IRUGO, fani_led_show, fani_led_store, FAN_1);
+static SENSOR_DEVICE_ATTR(fan2_led, S_IRUGO, fani_led_show, fani_led_store, FAN_2);
+
+static struct attribute *n3248te_cpld_attrs[] = {
+    &dev_attr_sfp_txdis.attr,
+    &dev_attr_sfp_rxlos.attr,
+    &dev_attr_sfp_txfault.attr,
+    &dev_attr_sfp_modprs.attr,
+    &dev_attr_qsfp_modprs.attr,
+    &dev_attr_qsfp_rst.attr,
+    &dev_attr_reboot_cause.attr,
+    &dev_attr_power_reset.attr,
+    &sensor_dev_attr_fan0_dir.dev_attr.attr,
+    &sensor_dev_attr_fan1_dir.dev_attr.attr,
+    &sensor_dev_attr_fan2_dir.dev_attr.attr,
+    &sensor_dev_attr_fan0_prs.dev_attr.attr,
+    &sensor_dev_attr_fan1_prs.dev_attr.attr,
+    &sensor_dev_attr_fan2_prs.dev_attr.attr,
+    &sensor_dev_attr_fan0_led.dev_attr.attr,
+    &sensor_dev_attr_fan1_led.dev_attr.attr,
+    &sensor_dev_attr_fan2_led.dev_attr.attr,
+    &dev_attr_psu0_prs.attr,
+    &dev_attr_psu1_prs.attr,
+    &dev_attr_psu0_status.attr,
+    &dev_attr_psu1_status.attr,
+    &dev_attr_system_led.attr,
+    &dev_attr_locator_led.attr,
+    &dev_attr_power_led.attr,
+    &dev_attr_master_led.attr,
+    &dev_attr_fan_led.attr,
+    &dev_attr_power_good.attr,
+    &dev_attr_sys_cpld_mjr_ver.attr,
+    &dev_attr_sys_cpld_mnr_ver.attr,
+    &dev_attr_cpu_cpld_mjr_ver.attr,
+    &dev_attr_cpu_cpld_mnr_ver.attr,
+    NULL,
+};
+
+static struct attribute_group n3248te_cpld_attr_grp = {
+    .attrs = n3248te_cpld_attrs,
+};
+
+static int get_ismt_base_nr(void)
+{
+    struct i2c_adapter *ismt_adap;
+    static int ismt_base_nr = -1;
+
+    if (ismt_base_nr != -1) {
+        return ismt_base_nr;
+    }
+    for (ismt_base_nr = 0; ismt_base_nr < 2; ismt_base_nr++) {
+        ismt_adap = i2c_get_adapter(ismt_base_nr);
+        if (!ismt_adap) {
+            printk(KERN_WARNING "iSMT adapter (%d) not found\n", ismt_base_nr);
+            return -ENODEV;
+        }
+        if (!strstr(ismt_adap->name, "iSMT adapter")) {
+            i2c_put_adapter(ismt_adap);
+            printk("I2C %d adapter is %s\n", ismt_base_nr, ismt_adap->name);
+        } else {
+            i2c_put_adapter(ismt_adap);
+            return ismt_base_nr;
+        }
+    }
+    return -ENODEV;
+}
+
+static int __init cpld_probe(struct platform_device *pdev)
+{
+    struct cpld_platform_data *pdata;
+    struct i2c_adapter *parent;
+    int i, cpld_bus;
+    int ret;
+
+    pdata = pdev->dev.platform_data;
+    if (!pdata) {
+        dev_err(&pdev->dev, "Missing platform data\n");
+        return -ENODEV;
+    }
+
+    cpld_bus = get_ismt_base_nr();
+    if (cpld_bus < 0) {
+        return -ENODEV;
+    }
+    parent = i2c_get_adapter(cpld_bus);
+    if (!parent) {
+        printk(KERN_WARNING "Parent adapter (%d) not found\n", cpld_bus);
+        return -ENODEV;
+    }
+    for (i = 0; i < CPLD_DEVICE_NUM; i++) {
+        pdata[i].client = i2c_new_dummy(parent, pdata[i].reg_addr);
+        if (!pdata[i].client) {
+            printk(KERN_WARNING "Fail to create dummy i2c client for addr %d\n", pdata[i].reg_addr);
+            goto error;
+        }
+    }
+
+    ret = sysfs_create_group(&pdev->dev.kobj, &n3248te_cpld_attr_grp);
+    if (ret)
+        goto error;
+
+    return 0;
+
+error:
+    i--;
+    for (; i >= 0; i--) {
+        if (pdata[i].client) {
+            i2c_unregister_device(pdata[i].client);
+        }
+    }
+
+    i2c_put_adapter(parent);
+
+    return -ENODEV;
+}
+
+static int __exit cpld_remove(struct platform_device *pdev)
+{
+    int i;
+    struct i2c_adapter *parent = NULL;
+    struct cpld_platform_data *pdata = pdev->dev.platform_data;
+
+    sysfs_remove_group(&pdev->dev.kobj, &n3248te_cpld_attr_grp);
+
+    if (!pdata) {
+        dev_err(&pdev->dev, "Missing platform data\n");
+    } else {
+        for (i = 0; i < CPLD_DEVICE_NUM; i++) {
+            if (pdata[i].client) {
+                if (!parent) {
+                    parent = (pdata[i].client)->adapter;
+                }
+                i2c_unregister_device(pdata[i].client);
+            }
+        }
+    }
+
+    i2c_put_adapter(parent);
+
+    return 0;
+}
+
+static struct platform_driver cpld_driver = {
+    .probe  = cpld_probe,
+    .remove = __exit_p(cpld_remove),
+    .driver = {
+        .owner  = THIS_MODULE,
+        .name   = "dell-n3248te-cpld",
+    },
+};
+
+static struct i2c_board_info sys_board_mux[] = {
+    {
+        I2C_BOARD_INFO("pca9548", 0x71)
+    }
+};
+
+static int __init dell_n3248te_platform_init(void)
+{
+    int ret = 0;
+    struct i2c_adapter *sys_i2c_adap;
+    struct i2c_client  *mux_i2c_cli;
+    struct cpld_platform_data *cpld_pdata;
+    struct mux_platform_data *pdata;
+    int i, sys_i2c_bus;
+
+    printk("dell_n3248te_platform module initialization\n");
+    sys_i2c_bus = get_ismt_base_nr();
+    if (sys_i2c_bus < 0) {
+        return -ENODEV;
+    }
+
+    sys_i2c_adap = i2c_get_adapter(sys_i2c_bus);
+    mux_i2c_cli = i2c_new_device(sys_i2c_adap, sys_board_mux);
+    if (!mux_i2c_cli)
+        return PTR_ERR_OR_ZERO(mux_i2c_cli);
+
+    ret = platform_driver_register(&cpld_driver);
+    if (ret) {
+        printk(KERN_WARNING "Fail to register cpld driver\n");
+        goto error_cpld_driver;
+    }
+
+    ret = platform_driver_register(&mux_driver);
+    if (ret) {
+        printk(KERN_WARNING "Fail to register mux driver\n");
+        goto error_mux_driver;
+    }
+
+    ret = platform_device_register(&n3248te_cpld);
+    if (ret) {
+        printk(KERN_WARNING "Fail to create cpld device\n");
+        goto error_cpld;
+    }
+
+    cpld_pdata = n3248te_cpld.dev.platform_data;
+
+    for (i = 0; i < PF_MUX_DEVICES; i++) {
+        pdata = n3248te_mux[i].dev.platform_data;
+        pdata->cpld = cpld_pdata[sys_cpld].client;
+        ret = platform_device_register(&n3248te_mux[i]);
+        if (ret) {
+            printk(KERN_WARNING "fail to create mux %d\n", i);
+            goto error_mux;
+        }
+    }
+    ret = i2c_smbus_write_byte_data(cpld_pdata[sys_cpld].client, PHY_RESET_REG, RESET_ALL_PHY);
+    if (ret)
+        goto error_mux;
+
+    return 0;
+
+error_mux:
+    i--;
+    for (; i >= 0; i--) {
+        platform_device_unregister(&n3248te_mux[i]);
+    }
+    platform_device_unregister(&n3248te_cpld);
+error_cpld:
+    platform_driver_unregister(&mux_driver);
+error_mux_driver:
+    platform_driver_unregister(&cpld_driver);
+error_cpld_driver:
+    return ret;
+}
+
+static void __exit dell_n3248te_platform_exit(void)
+{
+    int i;
+
+    for (i = 0; i < PF_MUX_DEVICES; i++)
+        platform_device_unregister(&n3248te_mux[i]);
+    platform_device_unregister(&n3248te_cpld);
+    platform_driver_unregister(&cpld_driver);
+    platform_driver_unregister(&mux_driver);
+}
+
+module_init(dell_n3248te_platform_init);
+module_exit(dell_n3248te_platform_exit);
+
+MODULE_DESCRIPTION("DELL N3248TE Platform Support");
+MODULE_AUTHOR("Dhanakumar Subramanian <dhanakumar_subramani@dell.com>");
+MODULE_LICENSE("GPL");
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/modules/emc2305.c b/platform/broadcom/sonic-platform-modules-dell/n3248te/modules/emc2305.c
new file mode 100644
index 000000000000..f08033e080ce
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/modules/emc2305.c
@@ -0,0 +1,877 @@
+/*
+ * emc2305.c - hwmon driver for SMSC EMC2305 fan controller
+ * (C) Copyright 2013
+ * Reinhard Pfau, Guntermann & Drunck GmbH <pfau@gdsys.de>
+ *
+ * Based on emc2103 driver by SMSC.
+ *
+ * Datasheet available at:
+ * http://www.smsc.com/Downloads/SMSC/Downloads_Public/Data_Sheets/2305.pdf
+ *
+ * Also supports the EMC2303 fan controller which has the same functionality
+ * and register layout as EMC2305, but supports only up to 3 fans instead of 5.
+ *
+ * Also supports EMC2302 (up to 2 fans) and EMC2301 (1 fan) fan controller.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * TODO / IDEAS:
+ * - expose more of the configuration and features
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+
+/*
+ * Addresses scanned.
+ * Listed in the same order as they appear in the EMC2305, EMC2303 data sheets.
+ *
+ * Note: these are the I2C adresses which are possible for EMC2305 and EMC2303
+ * chips.
+ * The EMC2302 supports only 0x2e (EMC2302-1) and 0x2f (EMC2302-2).
+ * The EMC2301 supports only 0x2f.
+ */
+static const unsigned short i2c_adresses[] = {
+	0x2E,
+	0x2F,
+	0x2C,
+	0x2D,
+	0x4C,
+	0x4D,
+	I2C_CLIENT_END
+};
+
+/*
+ * global registers
+ */
+enum {
+	REG_CONFIGURATION = 0x20,
+	REG_FAN_STATUS = 0x24,
+	REG_FAN_STALL_STATUS = 0x25,
+	REG_FAN_SPIN_STATUS = 0x26,
+	REG_DRIVE_FAIL_STATUS = 0x27,
+	REG_FAN_INTERRUPT_ENABLE = 0x29,
+	REG_PWM_POLARITY_CONFIG = 0x2a,
+	REG_PWM_OUTPUT_CONFIG = 0x2b,
+	REG_PWM_BASE_FREQ_1 = 0x2c,
+	REG_PWM_BASE_FREQ_2 = 0x2d,
+	REG_SOFTWARE_LOCK = 0xef,
+	REG_PRODUCT_FEATURES = 0xfc,
+	REG_PRODUCT_ID = 0xfd,
+	REG_MANUFACTURER_ID = 0xfe,
+	REG_REVISION = 0xff
+};
+
+/*
+ * fan specific registers
+ */
+enum {
+	REG_FAN_SETTING = 0x30,
+	REG_PWM_DIVIDE = 0x31,
+	REG_FAN_CONFIGURATION_1 = 0x32,
+	REG_FAN_CONFIGURATION_2 = 0x33,
+	REG_GAIN = 0x35,
+	REG_FAN_SPIN_UP_CONFIG = 0x36,
+	REG_FAN_MAX_STEP = 0x37,
+	REG_FAN_MINIMUM_DRIVE = 0x38,
+	REG_FAN_VALID_TACH_COUNT = 0x39,
+	REG_FAN_DRIVE_FAIL_BAND_LOW = 0x3a,
+	REG_FAN_DRIVE_FAIL_BAND_HIGH = 0x3b,
+	REG_TACH_TARGET_LOW = 0x3c,
+	REG_TACH_TARGET_HIGH = 0x3d,
+	REG_TACH_READ_HIGH = 0x3e,
+	REG_TACH_READ_LOW = 0x3f,
+};
+
+#define SEL_FAN(fan, reg) (reg + fan * 0x10)
+
+/*
+ * Factor by equations [2] and [3] from data sheet; valid for fans where the
+ * number of edges equals (poles * 2 + 1).
+ */
+#define FAN_RPM_FACTOR 3932160
+
+
+struct emc2305_fan_data {
+	bool		enabled;
+	bool		valid;
+	unsigned long	last_updated;
+	bool		rpm_control;
+	u8		multiplier;
+	u8		poles;
+	u16		target;
+	u16		tach;
+	u16		rpm_factor;
+	u8		pwm;
+};
+
+struct emc2305_data {
+	struct device		*hwmon_dev;
+	struct mutex		update_lock;
+	int			fans;
+	struct emc2305_fan_data	fan[5];
+};
+
+static int read_u8_from_i2c(struct i2c_client *client, u8 i2c_reg, u8 *output)
+{
+	int status = i2c_smbus_read_byte_data(client, i2c_reg);
+	if (status < 0) {
+		dev_warn(&client->dev, "reg 0x%02x, err %d\n",
+			i2c_reg, status);
+	} else {
+		*output = status;
+	}
+	return status;
+}
+
+static void read_fan_from_i2c(struct i2c_client *client, u16 *output,
+			      u8 hi_addr, u8 lo_addr)
+{
+	u8 high_byte, lo_byte;
+
+	if (read_u8_from_i2c(client, hi_addr, &high_byte) < 0)
+		return;
+
+	if (read_u8_from_i2c(client, lo_addr, &lo_byte) < 0)
+		return;
+
+	*output = ((u16)high_byte << 5) | (lo_byte >> 3);
+}
+
+static void write_fan_target_to_i2c(struct i2c_client *client, int fan,
+				    u16 new_target)
+{
+	const u8 lo_reg = SEL_FAN(fan, REG_TACH_TARGET_LOW);
+	const u8 hi_reg = SEL_FAN(fan, REG_TACH_TARGET_HIGH);
+	u8 high_byte = (new_target & 0x1fe0) >> 5;
+	u8 low_byte = (new_target & 0x001f) << 3;
+	i2c_smbus_write_byte_data(client, lo_reg, low_byte);
+	i2c_smbus_write_byte_data(client, hi_reg, high_byte);
+}
+
+static void read_fan_config_from_i2c(struct i2c_client *client, int fan)
+
+{
+	struct emc2305_data *data = i2c_get_clientdata(client);
+	u8 conf1;
+
+	if (read_u8_from_i2c(client, SEL_FAN(fan, REG_FAN_CONFIGURATION_1),
+			     &conf1) < 0)
+		return;
+
+	data->fan[fan].rpm_control = (conf1 & 0x80) != 0;
+	data->fan[fan].multiplier = 1 << ((conf1 & 0x60) >> 5);
+	data->fan[fan].poles = ((conf1 & 0x18) >> 3) + 1;
+}
+
+static void read_fan_setting(struct i2c_client *client, int fan)
+{
+	struct emc2305_data *data = i2c_get_clientdata(client);
+	u8 setting;
+
+	if (read_u8_from_i2c(client, SEL_FAN(fan, REG_FAN_SETTING),
+			     &setting) < 0)
+		return;
+
+	data->fan[fan].pwm = setting;
+}
+
+static void read_fan_data(struct i2c_client *client, int fan_idx)
+{
+	struct emc2305_data *data = i2c_get_clientdata(client);
+
+	read_fan_from_i2c(client, &data->fan[fan_idx].target,
+			  SEL_FAN(fan_idx, REG_TACH_TARGET_HIGH),
+			  SEL_FAN(fan_idx, REG_TACH_TARGET_LOW));
+	read_fan_from_i2c(client, &data->fan[fan_idx].tach,
+			  SEL_FAN(fan_idx, REG_TACH_READ_HIGH),
+			  SEL_FAN(fan_idx, REG_TACH_READ_LOW));
+}
+
+static struct emc2305_fan_data *
+emc2305_update_fan(struct i2c_client *client, int fan_idx)
+{
+	struct emc2305_data *data = i2c_get_clientdata(client);
+	struct emc2305_fan_data *fan_data = &data->fan[fan_idx];
+
+	mutex_lock(&data->update_lock);
+
+	if (time_after(jiffies, fan_data->last_updated + HZ + HZ / 2)
+	    || !fan_data->valid) {
+		read_fan_config_from_i2c(client, fan_idx);
+		read_fan_data(client, fan_idx);
+		read_fan_setting(client, fan_idx);
+		fan_data->valid = true;
+		fan_data->last_updated = jiffies;
+	}
+
+	mutex_unlock(&data->update_lock);
+	return fan_data;
+}
+
+static struct emc2305_fan_data *
+emc2305_update_device_fan(struct device *dev, struct device_attribute *da)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	int fan_idx = to_sensor_dev_attr(da)->index;
+
+	return emc2305_update_fan(client, fan_idx);
+}
+
+/*
+ * set/ config functions
+ */
+
+/*
+ * Note: we also update the fan target here, because its value is
+ * determined in part by the fan clock divider.  This follows the principle
+ * of least surprise; the user doesn't expect the fan target to change just
+ * because the divider changed.
+ */
+static int
+emc2305_set_fan_div(struct i2c_client *client, int fan_idx, long new_div)
+{
+	struct emc2305_data *data = i2c_get_clientdata(client);
+	struct emc2305_fan_data *fan = emc2305_update_fan(client, fan_idx);
+	const u8 reg_conf1 = SEL_FAN(fan_idx, REG_FAN_CONFIGURATION_1);
+	int new_range_bits, old_div = 8 / fan->multiplier;
+	int status = 0;
+
+	if (new_div == old_div) /* No change */
+		return 0;
+
+	switch (new_div) {
+	case 1:
+		new_range_bits = 3;
+		break;
+	case 2:
+		new_range_bits = 2;
+		break;
+	case 4:
+		new_range_bits = 1;
+		break;
+	case 8:
+		new_range_bits = 0;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	mutex_lock(&data->update_lock);
+
+	status = i2c_smbus_read_byte_data(client, reg_conf1);
+	if (status < 0) {
+		dev_dbg(&client->dev, "reg 0x%02x, err %d\n",
+			reg_conf1, status);
+		status = -EIO;
+		goto exit_unlock;
+	}
+	status &= 0x9F;
+	status |= (new_range_bits << 5);
+	status = i2c_smbus_write_byte_data(client, reg_conf1, status);
+	if (status < 0) {
+		status = -EIO;
+		goto exit_invalidate;
+	}
+
+	fan->multiplier = 8 / new_div;
+
+	/* update fan target if high byte is not disabled */
+	if ((fan->target & 0x1fe0) != 0x1fe0) {
+		u16 new_target = (fan->target * old_div) / new_div;
+		fan->target = min_t(u16, new_target, 0x1fff);
+		write_fan_target_to_i2c(client, fan_idx, fan->target);
+	}
+
+exit_invalidate:
+	/* invalidate fan data to force re-read from hardware */
+	fan->valid = false;
+exit_unlock:
+	mutex_unlock(&data->update_lock);
+	return status;
+}
+
+static int
+emc2305_set_fan_target(struct i2c_client *client, int fan_idx, long rpm_target)
+{
+	struct emc2305_data *data = i2c_get_clientdata(client);
+	struct emc2305_fan_data *fan = emc2305_update_fan(client, fan_idx);
+
+	/*
+	 * Datasheet states 16000 as maximum RPM target
+	 * (table 2.2 and section 4.3)
+	 */
+	if ((rpm_target < 0) || (rpm_target > 16000))
+		return -EINVAL;
+
+	mutex_lock(&data->update_lock);
+
+	if (rpm_target == 0)
+		fan->target = 0x1fff;
+	else
+		fan->target = clamp_val(
+			(FAN_RPM_FACTOR * fan->multiplier) / rpm_target,
+			0, 0x1fff);
+
+	write_fan_target_to_i2c(client, fan_idx, fan->target);
+
+	mutex_unlock(&data->update_lock);
+	return 0;
+}
+
+static int
+emc2305_set_pwm_enable(struct i2c_client *client, int fan_idx, long enable)
+{
+	struct emc2305_data *data = i2c_get_clientdata(client);
+	struct emc2305_fan_data *fan = emc2305_update_fan(client, fan_idx);
+	const u8 reg_fan_conf1 = SEL_FAN(fan_idx, REG_FAN_CONFIGURATION_1);
+	int status = 0;
+	u8 conf_reg;
+
+	mutex_lock(&data->update_lock);
+	switch (enable) {
+	case 0:
+		fan->rpm_control = false;
+		break;
+	case 3:
+		fan->rpm_control = true;
+		break;
+	default:
+		status = -EINVAL;
+		goto exit_unlock;
+	}
+
+	status = read_u8_from_i2c(client, reg_fan_conf1, &conf_reg);
+	if (status < 0) {
+		status = -EIO;
+		goto exit_unlock;
+	}
+
+	if (fan->rpm_control)
+		conf_reg |= 0x80;
+	else
+		conf_reg &= ~0x80;
+
+	status = i2c_smbus_write_byte_data(client, reg_fan_conf1, conf_reg);
+	if (status < 0)
+		status = -EIO;
+
+exit_unlock:
+	mutex_unlock(&data->update_lock);
+	return status;
+}
+
+static int
+emc2305_set_pwm(struct i2c_client *client, int fan_idx, long pwm)
+{
+	struct emc2305_data *data = i2c_get_clientdata(client);
+	struct emc2305_fan_data *fan = emc2305_update_fan(client, fan_idx);
+	const u8 reg_fan_setting = SEL_FAN(fan_idx, REG_FAN_SETTING);
+	int status = 0;
+
+	/*
+	 * Datasheet states 255 as maximum PWM
+	 * (section 5.7)
+	 */
+	if ((pwm < 0) || (pwm > 255))
+		return -EINVAL;
+
+	fan->pwm = pwm;
+
+	mutex_lock(&data->update_lock);
+
+	status = i2c_smbus_write_byte_data(client, reg_fan_setting, fan->pwm);
+
+	mutex_unlock(&data->update_lock);
+	return status;
+}
+/*
+ * sysfs callback functions
+ *
+ * Note:
+ * Naming of the funcs is modelled after the naming scheme described in
+ * Documentation/hwmon/sysfs-interface:
+ *
+ * For a sysfs file <type><number>_<item> the functions are named like this:
+ *    the show function: show_<type>_<item>
+ *    the store function: set_<type>_<item>
+ * For read only (RO) attributes of course only the show func is required.
+ *
+ * This convention allows us to define the sysfs attributes by using macros.
+ */
+
+static ssize_t
+show_fan_input(struct device *dev, struct device_attribute *da, char *buf)
+{
+	struct emc2305_fan_data *fan = emc2305_update_device_fan(dev, da);
+	int rpm = 0;
+	if (fan->tach != 0)
+		rpm = (FAN_RPM_FACTOR * fan->multiplier) / fan->tach;
+	return sprintf(buf, "%d\n", rpm);
+}
+
+static ssize_t
+show_fan_fault(struct device *dev, struct device_attribute *da, char *buf)
+{
+	struct emc2305_fan_data *fan = emc2305_update_device_fan(dev, da);
+	bool fault = ((fan->tach & 0x1fe0) == 0x1fe0);
+	return sprintf(buf, "%d\n", fault ? 1 : 0);
+}
+
+static ssize_t
+show_fan_div(struct device *dev, struct device_attribute *da, char *buf)
+{
+	struct emc2305_fan_data *fan = emc2305_update_device_fan(dev, da);
+	int fan_div = 8 / fan->multiplier;
+	return sprintf(buf, "%d\n", fan_div);
+}
+
+static ssize_t
+set_fan_div(struct device *dev, struct device_attribute *da,
+	    const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	int fan_idx = to_sensor_dev_attr(da)->index;
+	long new_div;
+	int status;
+
+	status = kstrtol(buf, 10, &new_div);
+	if (status < 0)
+		return -EINVAL;
+
+	status = emc2305_set_fan_div(client, fan_idx, new_div);
+	if (status < 0)
+		return status;
+
+	return count;
+}
+
+static ssize_t
+show_fan_target(struct device *dev, struct device_attribute *da, char *buf)
+{
+	struct emc2305_fan_data *fan = emc2305_update_device_fan(dev, da);
+	int rpm = 0;
+
+	/* high byte of 0xff indicates disabled so return 0 */
+	if ((fan->target != 0) && ((fan->target & 0x1fe0) != 0x1fe0))
+		rpm = (FAN_RPM_FACTOR * fan->multiplier)
+			/ fan->target;
+
+	return sprintf(buf, "%d\n", rpm);
+}
+
+static ssize_t set_fan_target(struct device *dev, struct device_attribute *da,
+			      const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	int fan_idx = to_sensor_dev_attr(da)->index;
+	long rpm_target;
+	int status;
+
+	status = kstrtol(buf, 10, &rpm_target);
+	if (status < 0)
+		return -EINVAL;
+
+	status = emc2305_set_fan_target(client, fan_idx, rpm_target);
+	if (status < 0)
+		return status;
+
+	return count;
+}
+
+static ssize_t
+show_pwm_enable(struct device *dev, struct device_attribute *da, char *buf)
+{
+	struct emc2305_fan_data *fan = emc2305_update_device_fan(dev, da);
+	return sprintf(buf, "%d\n", fan->rpm_control ? 3 : 0);
+}
+
+static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *da,
+			      const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	int fan_idx = to_sensor_dev_attr(da)->index;
+	long new_value;
+	int status;
+
+	status = kstrtol(buf, 10, &new_value);
+	if (status < 0)
+		return -EINVAL;
+	status = emc2305_set_pwm_enable(client, fan_idx, new_value);
+	return count;
+}
+
+static ssize_t show_pwm(struct device *dev, struct device_attribute *da,
+			char *buf)
+{
+	struct emc2305_fan_data *fan = emc2305_update_device_fan(dev, da);
+	return sprintf(buf, "%d\n", fan->pwm);
+}
+
+static ssize_t set_pwm(struct device *dev, struct device_attribute *da,
+		       const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	int fan_idx = to_sensor_dev_attr(da)->index;
+	unsigned long val;
+	int ret;
+	int status;
+
+	ret = kstrtoul(buf, 10, &val);
+	if (ret)
+		return ret;
+	if (val > 255)
+		return -EINVAL;
+
+	status = emc2305_set_pwm(client, fan_idx, val);
+	return count;
+}
+
+/* define a read only attribute */
+#define EMC2305_ATTR_RO(_type, _item, _num)			\
+	SENSOR_ATTR(_type ## _num ## _ ## _item, S_IRUGO,	\
+		    show_## _type ## _ ## _item, NULL, _num - 1)
+
+/* define a read/write attribute */
+#define EMC2305_ATTR_RW(_type, _item, _num)				\
+	SENSOR_ATTR(_type ## _num ## _ ## _item, S_IRUGO | S_IWUSR,	\
+		    show_## _type ##_ ## _item,				\
+		    set_## _type ## _ ## _item, _num - 1)
+
+/*
+ * TODO: Ugly hack, but temporary as this whole logic needs
+ * to be rewritten as per standard HWMON sysfs registration
+ */
+
+/* define a read/write attribute */
+#define EMC2305_ATTR_RW2(_type, _num)				\
+	SENSOR_ATTR(_type ## _num, S_IRUGO | S_IWUSR,	\
+		    show_## _type, set_## _type, _num - 1)
+
+/* defines the attributes for a single fan */
+#define EMC2305_DEFINE_FAN_ATTRS(_num)					\
+	static const							\
+	struct sensor_device_attribute emc2305_attr_fan ## _num[] = {	\
+		EMC2305_ATTR_RO(fan, input, _num),			\
+		EMC2305_ATTR_RO(fan, fault, _num),			\
+		EMC2305_ATTR_RW(fan, div, _num),			\
+		EMC2305_ATTR_RW(fan, target, _num),			\
+		EMC2305_ATTR_RW(pwm, enable, _num),			\
+		EMC2305_ATTR_RW2(pwm, _num)			\
+	}
+
+#define EMC2305_NUM_FAN_ATTRS ARRAY_SIZE(emc2305_attr_fan1)
+
+/* common attributes for EMC2303 and EMC2305 */
+static const struct sensor_device_attribute emc2305_attr_common[] = {
+};
+
+/* fan attributes for the single fans */
+EMC2305_DEFINE_FAN_ATTRS(1);
+EMC2305_DEFINE_FAN_ATTRS(2);
+EMC2305_DEFINE_FAN_ATTRS(3);
+EMC2305_DEFINE_FAN_ATTRS(4);
+EMC2305_DEFINE_FAN_ATTRS(5);
+EMC2305_DEFINE_FAN_ATTRS(6);
+
+/* fan attributes */
+static const struct sensor_device_attribute *emc2305_fan_attrs[] = {
+	emc2305_attr_fan1,
+	emc2305_attr_fan2,
+	emc2305_attr_fan3,
+	emc2305_attr_fan4,
+	emc2305_attr_fan5,
+};
+
+/*
+ * driver interface
+ */
+
+static int emc2305_remove(struct i2c_client *client)
+{
+	struct emc2305_data *data = i2c_get_clientdata(client);
+	int fan_idx, i;
+
+	hwmon_device_unregister(data->hwmon_dev);
+
+	for (fan_idx = 0; fan_idx < data->fans; ++fan_idx)
+		for (i = 0; i < EMC2305_NUM_FAN_ATTRS; ++i)
+			device_remove_file(
+				&client->dev,
+				&emc2305_fan_attrs[fan_idx][i].dev_attr);
+
+	for (i = 0; i < ARRAY_SIZE(emc2305_attr_common); ++i)
+		device_remove_file(&client->dev,
+				   &emc2305_attr_common[i].dev_attr);
+
+	kfree(data);
+	return 0;
+}
+
+
+#ifdef CONFIG_OF
+/*
+ * device tree support
+ */
+
+struct of_fan_attribute {
+	const char *name;
+	int (*set)(struct i2c_client*, int, long);
+};
+
+struct of_fan_attribute of_fan_attributes[] = {
+	{"fan-div", emc2305_set_fan_div},
+	{"fan-target", emc2305_set_fan_target},
+	{"pwm-enable", emc2305_set_pwm_enable},
+	{NULL, NULL}
+};
+
+static int emc2305_config_of(struct i2c_client *client)
+{
+	struct emc2305_data *data = i2c_get_clientdata(client);
+	struct device_node *node;
+	unsigned int fan_idx;
+
+	if (!client->dev.of_node)
+		return -EINVAL;
+	if (!of_get_next_child(client->dev.of_node, NULL))
+		return  0;
+
+	for (fan_idx = 0; fan_idx < data->fans; ++fan_idx)
+		data->fan[fan_idx].enabled = false;
+
+	for_each_child_of_node(client->dev.of_node, node) {
+		const __be32 *property;
+		int len;
+		struct of_fan_attribute *attr;
+
+		property = of_get_property(node, "reg", &len);
+		if (!property || len != sizeof(int)) {
+			dev_err(&client->dev, "invalid reg on %s\n",
+				node->full_name);
+			continue;
+		}
+
+		fan_idx = be32_to_cpup(property);
+		if (fan_idx >= data->fans) {
+			dev_err(&client->dev,
+				"invalid fan index %d on %s\n",
+				fan_idx, node->full_name);
+			continue;
+		}
+
+		data->fan[fan_idx].enabled = true;
+
+		for (attr = of_fan_attributes; attr->name; ++attr) {
+			int status = 0;
+			long value;
+			property = of_get_property(node, attr->name, &len);
+			if (!property)
+				continue;
+			if (len != sizeof(int)) {
+				dev_err(&client->dev, "invalid %s on %s\n",
+					attr->name, node->full_name);
+				continue;
+			}
+			value = be32_to_cpup(property);
+			status = attr->set(client, fan_idx, value);
+			if (status == -EINVAL) {
+				dev_err(&client->dev,
+					"invalid value for %s on %s\n",
+					attr->name, node->full_name);
+			}
+		}
+	}
+
+	return 0;
+}
+
+#endif
+
+static void emc2305_get_config(struct i2c_client *client)
+{
+	int i;
+	struct emc2305_data *data = i2c_get_clientdata(client);
+
+	for (i = 0; i < data->fans; ++i) {
+		data->fan[i].enabled = true;
+		emc2305_update_fan(client, i);
+	}
+
+#ifdef CONFIG_OF
+	emc2305_config_of(client);
+#endif
+
+}
+
+static int
+emc2305_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+	struct emc2305_data *data;
+	int status;
+	int i;
+	int fan_idx;
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -EIO;
+
+	data = kzalloc(sizeof(struct emc2305_data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	i2c_set_clientdata(client, data);
+	mutex_init(&data->update_lock);
+
+	status = i2c_smbus_read_byte_data(client, REG_PRODUCT_ID);
+	switch (status) {
+	case 0x34: /* EMC2305 */
+		data->fans = 5;
+		break;
+	case 0x35: /* EMC2303 */
+		data->fans = 3;
+		break;
+	case 0x36: /* EMC2302 */
+		data->fans = 2;
+		break;
+	case 0x37: /* EMC2301 */
+		data->fans = 1;
+		break;
+	default:
+		if (status >= 0)
+			status = -EINVAL;
+		goto exit_free;
+	}
+
+	emc2305_get_config(client);
+
+	for (i = 0; i < ARRAY_SIZE(emc2305_attr_common); ++i) {
+		status = device_create_file(&client->dev,
+					    &emc2305_attr_common[i].dev_attr);
+		if (status)
+			goto exit_remove;
+	}
+	for (fan_idx = 0; fan_idx < data->fans; ++fan_idx)
+		for (i = 0; i < EMC2305_NUM_FAN_ATTRS; ++i) {
+			if (!data->fan[fan_idx].enabled)
+				continue;
+			status = device_create_file(
+				&client->dev,
+				&emc2305_fan_attrs[fan_idx][i].dev_attr);
+			if (status)
+				goto exit_remove_fans;
+		}
+
+	data->hwmon_dev = hwmon_device_register(&client->dev);
+	if (IS_ERR(data->hwmon_dev)) {
+		status = PTR_ERR(data->hwmon_dev);
+		goto exit_remove_fans;
+	}
+
+	dev_info(&client->dev, "%s: sensor '%s'\n",
+		 dev_name(data->hwmon_dev), client->name);
+
+	return 0;
+
+exit_remove_fans:
+	for (fan_idx = 0; fan_idx < data->fans; ++fan_idx)
+		for (i = 0; i < EMC2305_NUM_FAN_ATTRS; ++i)
+			device_remove_file(
+				&client->dev,
+				&emc2305_fan_attrs[fan_idx][i].dev_attr);
+
+exit_remove:
+	for (i = 0; i < ARRAY_SIZE(emc2305_attr_common); ++i)
+		device_remove_file(&client->dev,
+				   &emc2305_attr_common[i].dev_attr);
+exit_free:
+	kfree(data);
+	return status;
+}
+
+static const struct i2c_device_id emc2305_id[] = {
+	{ "emc2305", 0 },
+	{ "emc2303", 0 },
+	{ "emc2302", 0 },
+	{ "emc2301", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, emc2305_id);
+
+/* Return 0 if detection is successful, -ENODEV otherwise */
+static int
+emc2305_detect(struct i2c_client *new_client, struct i2c_board_info *info)
+{
+	struct i2c_adapter *adapter = new_client->adapter;
+	int manufacturer, product;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -ENODEV;
+
+	manufacturer =
+		i2c_smbus_read_byte_data(new_client, REG_MANUFACTURER_ID);
+	if (manufacturer != 0x5D)
+		return -ENODEV;
+
+	product = i2c_smbus_read_byte_data(new_client, REG_PRODUCT_ID);
+
+	switch (product) {
+	case 0x34:
+		strlcpy(info->type, "emc2305", I2C_NAME_SIZE);
+		break;
+	case 0x35:
+		strlcpy(info->type, "emc2303", I2C_NAME_SIZE);
+		break;
+	case 0x36:
+		strlcpy(info->type, "emc2302", I2C_NAME_SIZE);
+		break;
+	case 0x37:
+		strlcpy(info->type, "emc2301", I2C_NAME_SIZE);
+		break;
+	default:
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static struct i2c_driver emc2305_driver = {
+	.class		= I2C_CLASS_HWMON,
+	.driver = {
+		.name	= "emc2305",
+	},
+	.probe		= emc2305_probe,
+	.remove		= emc2305_remove,
+	.id_table	= emc2305_id,
+/*
+	.detect		= emc2305_detect,
+	.address_list	= i2c_adresses,
+*/
+};
+
+module_i2c_driver(emc2305_driver);
+
+MODULE_AUTHOR("Reinhard Pfau <pfau@gdsys.de>");
+MODULE_DESCRIPTION("SMSC EMC2305 hwmon driver");
+MODULE_LICENSE("GPL");
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/modules/pmbus.h b/platform/broadcom/sonic-platform-modules-dell/n3248te/modules/pmbus.h
new file mode 100644
index 000000000000..521baf6da49a
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/modules/pmbus.h
@@ -0,0 +1,425 @@
+/*
+ * pmbus.h - Common defines and structures for PMBus devices
+ *
+ * Copyright (c) 2010, 2011 Ericsson AB.
+ * Copyright (c) 2012 Guenter Roeck
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef PMBUS_H
+#define PMBUS_H
+
+#include <linux/bitops.h>
+#include <linux/regulator/driver.h>
+
+/*
+ * Registers
+ */
+enum pmbus_regs {
+        PMBUS_PAGE                      = 0x00,
+        PMBUS_OPERATION                 = 0x01,
+        PMBUS_ON_OFF_CONFIG             = 0x02,
+        PMBUS_CLEAR_FAULTS              = 0x03,
+        PMBUS_PHASE                     = 0x04,
+
+        PMBUS_CAPABILITY                = 0x19,
+        PMBUS_QUERY                     = 0x1A,
+
+        PMBUS_VOUT_MODE                 = 0x20,
+        PMBUS_VOUT_COMMAND              = 0x21,
+        PMBUS_VOUT_TRIM                 = 0x22,
+        PMBUS_VOUT_CAL_OFFSET           = 0x23,
+        PMBUS_VOUT_MAX                  = 0x24,
+        PMBUS_VOUT_MARGIN_HIGH          = 0x25,
+        PMBUS_VOUT_MARGIN_LOW           = 0x26,
+        PMBUS_VOUT_TRANSITION_RATE      = 0x27,
+        PMBUS_VOUT_DROOP                = 0x28,
+        PMBUS_VOUT_SCALE_LOOP           = 0x29,
+        PMBUS_VOUT_SCALE_MONITOR        = 0x2A,
+
+        PMBUS_COEFFICIENTS              = 0x30,
+        PMBUS_POUT_MAX                  = 0x31,
+
+        PMBUS_FAN_CONFIG_12             = 0x3A,
+        PMBUS_FAN_COMMAND_1             = 0x3B,
+        PMBUS_FAN_COMMAND_2             = 0x3C,
+        PMBUS_FAN_CONFIG_34             = 0x3D,
+        PMBUS_FAN_COMMAND_3             = 0x3E,
+        PMBUS_FAN_COMMAND_4             = 0x3F,
+
+        PMBUS_VOUT_OV_FAULT_LIMIT       = 0x40,
+        PMBUS_VOUT_OV_FAULT_RESPONSE    = 0x41,
+        PMBUS_VOUT_OV_WARN_LIMIT        = 0x42,
+        PMBUS_VOUT_UV_WARN_LIMIT        = 0x43,
+        PMBUS_VOUT_UV_FAULT_LIMIT       = 0x44,
+        PMBUS_VOUT_UV_FAULT_RESPONSE    = 0x45,
+        PMBUS_IOUT_OC_FAULT_LIMIT       = 0x46,
+        PMBUS_IOUT_OC_FAULT_RESPONSE    = 0x47,
+        PMBUS_IOUT_OC_LV_FAULT_LIMIT    = 0x48,
+        PMBUS_IOUT_OC_LV_FAULT_RESPONSE = 0x49,
+        PMBUS_IOUT_OC_WARN_LIMIT        = 0x4A,
+        PMBUS_IOUT_UC_FAULT_LIMIT       = 0x4B,
+        PMBUS_IOUT_UC_FAULT_RESPONSE    = 0x4C,
+
+        PMBUS_OT_FAULT_LIMIT            = 0x4F,
+        PMBUS_OT_FAULT_RESPONSE         = 0x50,
+        PMBUS_OT_WARN_LIMIT             = 0x51,
+        PMBUS_UT_WARN_LIMIT             = 0x52,
+        PMBUS_UT_FAULT_LIMIT            = 0x53,
+        PMBUS_UT_FAULT_RESPONSE         = 0x54,
+        PMBUS_VIN_OV_FAULT_LIMIT        = 0x55,
+        PMBUS_VIN_OV_FAULT_RESPONSE     = 0x56,
+        PMBUS_VIN_OV_WARN_LIMIT         = 0x57,
+        PMBUS_VIN_UV_WARN_LIMIT         = 0x58,
+        PMBUS_VIN_UV_FAULT_LIMIT        = 0x59,
+
+        PMBUS_IIN_OC_FAULT_LIMIT        = 0x5B,
+        PMBUS_IIN_OC_WARN_LIMIT         = 0x5D,
+
+        PMBUS_POUT_OP_FAULT_LIMIT       = 0x68,
+        PMBUS_POUT_OP_WARN_LIMIT        = 0x6A,
+        PMBUS_PIN_OP_WARN_LIMIT         = 0x6B,
+
+        PMBUS_STATUS_BYTE               = 0x78,
+        PMBUS_STATUS_WORD               = 0x79,
+        PMBUS_STATUS_VOUT               = 0x7A,
+        PMBUS_STATUS_IOUT               = 0x7B,
+        PMBUS_STATUS_INPUT              = 0x7C,
+        PMBUS_STATUS_TEMPERATURE        = 0x7D,
+        PMBUS_STATUS_CML                = 0x7E,
+        PMBUS_STATUS_OTHER              = 0x7F,
+        PMBUS_STATUS_MFR_SPECIFIC       = 0x80,
+        PMBUS_STATUS_FAN_12             = 0x81,
+        PMBUS_STATUS_FAN_34             = 0x82,
+
+        PMBUS_READ_VIN                  = 0x88,
+        PMBUS_READ_IIN                  = 0x89,
+        PMBUS_READ_VCAP                 = 0x8A,
+        PMBUS_READ_VOUT                 = 0x8B,
+        PMBUS_READ_IOUT                 = 0x8C,
+        PMBUS_READ_TEMPERATURE_1        = 0x8D,
+        PMBUS_READ_TEMPERATURE_2        = 0x8E,
+        PMBUS_READ_TEMPERATURE_3        = 0x8F,
+        PMBUS_READ_FAN_SPEED_1          = 0x90,
+        PMBUS_READ_FAN_SPEED_2          = 0x91,
+        PMBUS_READ_FAN_SPEED_3          = 0x92,
+        PMBUS_READ_FAN_SPEED_4          = 0x93,
+        PMBUS_READ_DUTY_CYCLE           = 0x94,
+        PMBUS_READ_FREQUENCY            = 0x95,
+        PMBUS_READ_POUT                 = 0x96,
+        PMBUS_READ_PIN                  = 0x97,
+
+        PMBUS_REVISION                  = 0x98,
+        PMBUS_MFR_ID                    = 0x99,
+        PMBUS_MFR_MODEL                 = 0x9A,
+        PMBUS_MFR_REVISION              = 0x9B,
+        PMBUS_MFR_LOCATION              = 0x9C,
+        PMBUS_MFR_DATE                  = 0x9D,
+        PMBUS_MFR_SERIAL                = 0x9E,
+
+/*
+ * Virtual registers.
+ * Useful to support attributes which are not supported by standard PMBus
+ * registers but exist as manufacturer specific registers on individual chips.
+ * Must be mapped to real registers in device specific code.
+ *
+ * Semantics:
+ * Virtual registers are all word size.
+ * READ registers are read-only; writes are either ignored or return an error.
+ * RESET registers are read/write. Reading reset registers returns zero
+ * (used for detection), writing any value causes the associated history to be
+ * reset.
+ * Virtual registers have to be handled in device specific driver code. Chip
+ * driver code returns non-negative register values if a virtual register is
+ * supported, or a negative error code if not. The chip driver may return
+ * -ENODATA or any other error code in this case, though an error code other
+ * than -ENODATA is handled more efficiently and thus preferred. Either case,
+ * the calling PMBus core code will abort if the chip driver returns an error
+ * code when reading or writing virtual registers.
+ */
+        PMBUS_VIRT_BASE                 = 0x100,
+        PMBUS_VIRT_READ_TEMP_AVG,
+        PMBUS_VIRT_READ_TEMP_MIN,
+        PMBUS_VIRT_READ_TEMP_MAX,
+        PMBUS_VIRT_RESET_TEMP_HISTORY,
+        PMBUS_VIRT_READ_VIN_AVG,
+        PMBUS_VIRT_READ_VIN_MIN,
+        PMBUS_VIRT_READ_VIN_MAX,
+        PMBUS_VIRT_RESET_VIN_HISTORY,
+        PMBUS_VIRT_READ_IIN_AVG,
+        PMBUS_VIRT_READ_IIN_MIN,
+        PMBUS_VIRT_READ_IIN_MAX,
+        PMBUS_VIRT_RESET_IIN_HISTORY,
+        PMBUS_VIRT_READ_PIN_AVG,
+        PMBUS_VIRT_READ_PIN_MIN,
+        PMBUS_VIRT_READ_PIN_MAX,
+        PMBUS_VIRT_RESET_PIN_HISTORY,
+        PMBUS_VIRT_READ_POUT_AVG,
+        PMBUS_VIRT_READ_POUT_MIN,
+        PMBUS_VIRT_READ_POUT_MAX,
+        PMBUS_VIRT_RESET_POUT_HISTORY,
+        PMBUS_VIRT_READ_VOUT_AVG,
+        PMBUS_VIRT_READ_VOUT_MIN,
+        PMBUS_VIRT_READ_VOUT_MAX,
+        PMBUS_VIRT_RESET_VOUT_HISTORY,
+        PMBUS_VIRT_READ_IOUT_AVG,
+        PMBUS_VIRT_READ_IOUT_MIN,
+        PMBUS_VIRT_READ_IOUT_MAX,
+        PMBUS_VIRT_RESET_IOUT_HISTORY,
+        PMBUS_VIRT_READ_TEMP2_AVG,
+        PMBUS_VIRT_READ_TEMP2_MIN,
+        PMBUS_VIRT_READ_TEMP2_MAX,
+        PMBUS_VIRT_RESET_TEMP2_HISTORY,
+
+        PMBUS_VIRT_READ_VMON,
+        PMBUS_VIRT_VMON_UV_WARN_LIMIT,
+        PMBUS_VIRT_VMON_OV_WARN_LIMIT,
+        PMBUS_VIRT_VMON_UV_FAULT_LIMIT,
+        PMBUS_VIRT_VMON_OV_FAULT_LIMIT,
+        PMBUS_VIRT_STATUS_VMON,
+};
+
+/*
+ * OPERATION
+ */
+#define PB_OPERATION_CONTROL_ON         BIT(7)
+
+/*
+ * CAPABILITY
+ */
+#define PB_CAPABILITY_SMBALERT          BIT(4)
+#define PB_CAPABILITY_ERROR_CHECK       BIT(7)
+
+/*
+ * VOUT_MODE
+ */
+#define PB_VOUT_MODE_MODE_MASK          0xe0
+#define PB_VOUT_MODE_PARAM_MASK         0x1f
+
+#define PB_VOUT_MODE_LINEAR             0x00
+#define PB_VOUT_MODE_VID                0x20
+#define PB_VOUT_MODE_DIRECT             0x40
+
+/*
+ * Fan configuration
+ */
+#define PB_FAN_2_PULSE_MASK             (BIT(0) | BIT(1))
+#define PB_FAN_2_RPM                    BIT(2)
+#define PB_FAN_2_INSTALLED              BIT(3)
+#define PB_FAN_1_PULSE_MASK             (BIT(4) | BIT(5))
+#define PB_FAN_1_RPM                    BIT(6)
+#define PB_FAN_1_INSTALLED              BIT(7)
+
+/*
+ * STATUS_BYTE, STATUS_WORD (lower)
+ */
+#define PB_STATUS_NONE_ABOVE            BIT(0)
+#define PB_STATUS_CML                   BIT(1)
+#define PB_STATUS_TEMPERATURE           BIT(2)
+#define PB_STATUS_VIN_UV                BIT(3)
+#define PB_STATUS_IOUT_OC               BIT(4)
+#define PB_STATUS_VOUT_OV               BIT(5)
+#define PB_STATUS_OFF                   BIT(6)
+#define PB_STATUS_BUSY                  BIT(7)
+
+/*
+ * STATUS_WORD (upper)
+ */
+#define PB_STATUS_UNKNOWN               BIT(8)
+#define PB_STATUS_OTHER                 BIT(9)
+#define PB_STATUS_FANS                  BIT(10)
+#define PB_STATUS_POWER_GOOD_N          BIT(11)
+#define PB_STATUS_WORD_MFR              BIT(12)
+#define PB_STATUS_INPUT                 BIT(13)
+#define PB_STATUS_IOUT_POUT             BIT(14)
+#define PB_STATUS_VOUT                  BIT(15)
+
+/*
+ * STATUS_IOUT
+ */
+#define PB_POUT_OP_WARNING              BIT(0)
+#define PB_POUT_OP_FAULT                BIT(1)
+#define PB_POWER_LIMITING               BIT(2)
+#define PB_CURRENT_SHARE_FAULT          BIT(3)
+#define PB_IOUT_UC_FAULT                BIT(4)
+#define PB_IOUT_OC_WARNING              BIT(5)
+#define PB_IOUT_OC_LV_FAULT             BIT(6)
+#define PB_IOUT_OC_FAULT                BIT(7)
+
+/*
+ * STATUS_VOUT, STATUS_INPUT
+ */
+#define PB_VOLTAGE_UV_FAULT             BIT(4)
+#define PB_VOLTAGE_UV_WARNING           BIT(5)
+#define PB_VOLTAGE_OV_WARNING           BIT(6)
+#define PB_VOLTAGE_OV_FAULT             BIT(7)
+
+/*
+ * STATUS_INPUT
+ */
+#define PB_PIN_OP_WARNING               BIT(0)
+#define PB_IIN_OC_WARNING               BIT(1)
+#define PB_IIN_OC_FAULT                 BIT(2)
+
+/*
+ * STATUS_TEMPERATURE
+ */
+#define PB_TEMP_UT_FAULT                BIT(4)
+#define PB_TEMP_UT_WARNING              BIT(5)
+#define PB_TEMP_OT_WARNING              BIT(6)
+#define PB_TEMP_OT_FAULT                BIT(7)
+
+/*
+ * STATUS_FAN
+ */
+#define PB_FAN_AIRFLOW_WARNING          BIT(0)
+#define PB_FAN_AIRFLOW_FAULT            BIT(1)
+#define PB_FAN_FAN2_SPEED_OVERRIDE      BIT(2)
+#define PB_FAN_FAN1_SPEED_OVERRIDE      BIT(3)
+#define PB_FAN_FAN2_WARNING             BIT(4)
+#define PB_FAN_FAN1_WARNING             BIT(5)
+#define PB_FAN_FAN2_FAULT               BIT(6)
+#define PB_FAN_FAN1_FAULT               BIT(7)
+
+/*
+ * CML_FAULT_STATUS
+ */
+#define PB_CML_FAULT_OTHER_MEM_LOGIC    BIT(0)
+#define PB_CML_FAULT_OTHER_COMM         BIT(1)
+#define PB_CML_FAULT_PROCESSOR          BIT(3)
+#define PB_CML_FAULT_MEMORY             BIT(4)
+#define PB_CML_FAULT_PACKET_ERROR       BIT(5)
+#define PB_CML_FAULT_INVALID_DATA       BIT(6)
+#define PB_CML_FAULT_INVALID_COMMAND    BIT(7)
+
+enum pmbus_sensor_classes {
+        PSC_VOLTAGE_IN = 0,
+        PSC_VOLTAGE_OUT,
+        PSC_CURRENT_IN,
+        PSC_CURRENT_OUT,
+        PSC_POWER,
+        PSC_TEMPERATURE,
+        PSC_FAN,
+        PSC_NUM_CLASSES         /* Number of power sensor classes */
+};
+
+#define PMBUS_PAGES     32      /* Per PMBus specification */
+
+/* Functionality bit mask */
+#define PMBUS_HAVE_VIN          BIT(0)
+#define PMBUS_HAVE_VCAP         BIT(1)
+#define PMBUS_HAVE_VOUT         BIT(2)
+#define PMBUS_HAVE_IIN          BIT(3)
+#define PMBUS_HAVE_IOUT         BIT(4)
+#define PMBUS_HAVE_PIN          BIT(5)
+#define PMBUS_HAVE_POUT         BIT(6)
+#define PMBUS_HAVE_FAN12        BIT(7)
+#define PMBUS_HAVE_FAN34        BIT(8)
+#define PMBUS_HAVE_TEMP         BIT(9)
+#define PMBUS_HAVE_TEMP2        BIT(10)
+#define PMBUS_HAVE_TEMP3        BIT(11)
+#define PMBUS_HAVE_STATUS_VOUT  BIT(12)
+#define PMBUS_HAVE_STATUS_IOUT  BIT(13)
+#define PMBUS_HAVE_STATUS_INPUT BIT(14)
+#define PMBUS_HAVE_STATUS_TEMP  BIT(15)
+#define PMBUS_HAVE_STATUS_FAN12 BIT(16)
+#define PMBUS_HAVE_STATUS_FAN34 BIT(17)
+#define PMBUS_HAVE_VMON         BIT(18)
+#define PMBUS_HAVE_STATUS_VMON  BIT(19)
+
+enum pmbus_data_format { linear = 0, direct, vid };
+enum vrm_version { vr11 = 0, vr12 };
+
+struct pmbus_driver_info {
+        int pages;              /* Total number of pages */
+        enum pmbus_data_format format[PSC_NUM_CLASSES];
+        enum vrm_version vrm_version;
+        /*
+         * Support one set of coefficients for each sensor type
+         * Used for chips providing data in direct mode.
+         */
+        int m[PSC_NUM_CLASSES]; /* mantissa for direct data format */
+        int b[PSC_NUM_CLASSES]; /* offset */
+        int R[PSC_NUM_CLASSES]; /* exponent */
+
+        u32 func[PMBUS_PAGES];  /* Functionality, per page */
+        /*
+         * The following functions map manufacturing specific register values
+         * to PMBus standard register values. Specify only if mapping is
+         * necessary.
+         * Functions return the register value (read) or zero (write) if
+         * successful. A return value of -ENODATA indicates that there is no
+         * manufacturer specific register, but that a standard PMBus register
+         * may exist. Any other negative return value indicates that the
+         * register does not exist, and that no attempt should be made to read
+         * the standard register.
+         */
+        int (*read_byte_data)(struct i2c_client *client, int page, int reg);
+        int (*read_word_data)(struct i2c_client *client, int page, int reg);
+        int (*write_word_data)(struct i2c_client *client, int page, int reg,
+                               u16 word);
+        int (*write_byte)(struct i2c_client *client, int page, u8 value);
+        /*
+         * The identify function determines supported PMBus functionality.
+         * This function is only necessary if a chip driver supports multiple
+         * chips, and the chip functionality is not pre-determined.
+         */
+        int (*identify)(struct i2c_client *client,
+                        struct pmbus_driver_info *info);
+
+        /* Regulator functionality, if supported by this chip driver. */
+        int num_regulators;
+        const struct regulator_desc *reg_desc;
+};
+
+/* Regulator ops */
+
+extern const struct regulator_ops pmbus_regulator_ops;
+
+/* Macro for filling in array of struct regulator_desc */
+#define PMBUS_REGULATOR(_name, _id)                             \
+        [_id] = {                                               \
+                .name = (_name # _id),                          \
+                .id = (_id),                                    \
+                .of_match = of_match_ptr(_name # _id),          \
+                .regulators_node = of_match_ptr("regulators"),  \
+                .ops = &pmbus_regulator_ops,                    \
+                .type = REGULATOR_VOLTAGE,                      \
+                .owner = THIS_MODULE,                           \
+        }
+
+/* Function declarations */
+
+void pmbus_clear_cache(struct i2c_client *client);
+int pmbus_set_page(struct i2c_client *client, u8 page);
+int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg);
+int pmbus_write_word_data(struct i2c_client *client, u8 page, u8 reg, u16 word);
+int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg);
+int pmbus_write_byte(struct i2c_client *client, int page, u8 value);
+int pmbus_write_byte_data(struct i2c_client *client, int page, u8 reg,
+                          u8 value);
+int pmbus_update_byte_data(struct i2c_client *client, int page, u8 reg,
+                           u8 mask, u8 value);
+void pmbus_clear_faults(struct i2c_client *client);
+bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg);
+bool pmbus_check_word_register(struct i2c_client *client, int page, int reg);
+int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id,
+                   struct pmbus_driver_info *info);
+int pmbus_do_remove(struct i2c_client *client);
+const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client
+                                                      *client);
+
+#endif /* PMBUS_H */
\ No newline at end of file
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/fancontrol.sh b/platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/fancontrol.sh
new file mode 100755
index 000000000000..448ec5acb38c
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/fancontrol.sh
@@ -0,0 +1,78 @@
+#! /bin/sh
+
+### BEGIN INIT INFO
+# Provides:          fancontrol
+# Required-Start:    $remote_fs
+# Required-Stop:     $remote_fs
+# Default-Start:     2 3 4 5
+# Default-Stop:
+# Short-Description: fancontrol
+# Description:       fan speed regulator
+### END INIT INFO
+
+. /lib/lsb/init-functions
+
+[ -f /etc/default/rcS ] && . /etc/default/rcS
+PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin
+DAEMON=/usr/local/bin/fancontrol
+DESC="fan speed regulator"
+NAME="fancontrol"
+PIDFILE=/var/run/fancontrol.pid
+PLATFORMPATH=/sys/devices/platform/LPC
+MAIN_CONF=/usr/share/sonic/device/x86_64-dell_s3000_c2338-r0/fancontrol
+DEVPATH=/sys/devices/pci0000:00/0000:00:13.0/i2c-0/i2c-8/i2c-23/23-004d
+
+test -x $DAEMON || exit 0
+
+for i in 1 2 3
+do
+	j=$i
+	[ $i -eq 3 ] && j=4
+	FANFAULT=$(cat ${DEVPATH}/fan${j}_fault)
+  [ $FANFAULT = 1 ] && continue
+	FANDIR=$(cat ${PLATFORMPATH}/fan${i}_dir)
+done
+CONF=${MAIN_CONF}-${FANDIR}
+
+case "$1" in
+  start)
+        if [ -f $CONF ] ; then
+		if $DAEMON --check $CONF 1>/dev/null 2>/dev/null ; then
+			log_daemon_msg "Starting $DESC" "$NAME\n"
+			start-stop-daemon --start --quiet --pidfile $PIDFILE --startas $DAEMON $CONF
+			log_end_msg $?
+		else
+			log_failure_msg "Not starting fancontrol, broken configuration file; please re-run pwmconfig."
+		fi
+	else
+		if [ "$VERBOSE" != no ]; then
+			log_warning_msg "Not starting fancontrol; run pwmconfig first."
+		fi
+	fi
+	;;
+  stop)
+		log_daemon_msg "Stopping $DESC" "$NAME"
+		start-stop-daemon --stop --quiet --pidfile $PIDFILE --oknodo --startas $DAEMON $CONF
+		rm -f $PIDFILE
+		log_end_msg $?
+	;;
+  restart)
+        $0 stop
+		sleep 3
+		$0 start
+	;;
+  force-reload)
+	if start-stop-daemon --stop --test --quiet --pidfile $PIDFILE --startas $DAEMON $CONF ; then
+		$0 restart
+	fi
+	;;
+  status)
+		status_of_proc $DAEMON $NAME $CONF && exit 0 || exit $?
+	;;
+  *)
+	log_success_msg "Usage: /etc/init.d/fancontrol {start|stop|restart|force-reload|status}"
+	exit 1
+	;;
+esac
+
+exit 0
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/n3248te_platform.sh b/platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/n3248te_platform.sh
new file mode 100755
index 000000000000..e4c0734b1fd9
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/n3248te_platform.sh
@@ -0,0 +1,143 @@
+#!/bin/bash
+
+#platform init script for Dell N3248TE
+
+source dell_i2c_utils.sh
+
+#Attach/Detach the system devices
+sys_devices() {
+    case $1 in
+        "new_device")    #syseeprom
+                         i2c_config "echo 24c02 0x50 > /sys/bus/i2c/devices/i2c-2/$1"
+                         #Attach Fan Controller
+                         i2c_config "echo emc2305 0x2c > /sys/bus/i2c/devices/i2c-7/$1"
+                         #Attach temperature monitor
+                         i2c_config "echo tmp75 0x49 > /sys/bus/i2c/devices/i2c-7/$1"
+                         i2c_config "echo tmp75 0x4a > /sys/bus/i2c/devices/i2c-7/$1"
+                         i2c_config "echo tmp75 0x4b > /sys/bus/i2c/devices/i2c-7/$1"
+                         i2c_config "echo tmp75 0x4c > /sys/bus/i2c/devices/i2c-7/$1"
+                         i2c_config "echo tmp75 0x4f > /sys/bus/i2c/devices/i2c-7/$1"
+                         #Attach PSU Controller
+                         i2c_config "echo dps460 0x5e > /sys/bus/i2c/devices/i2c-10/$1"
+                         i2c_config "echo dps460 0x5e > /sys/bus/i2c/devices/i2c-11/$1"
+                         #Attach PSU EEPROM
+                         i2c_config "echo 24c02 0x56 > /sys/bus/i2c/devices/i2c-10/$1"
+                         i2c_config "echo 24c02 0x56 > /sys/bus/i2c/devices/i2c-11/$1"
+                         #Attach Fan EEPROM
+                         i2c_config "echo 24c02 0x50 > /sys/bus/i2c/devices/i2c-15/$1"
+                         i2c_config "echo 24c02 0x50 > /sys/bus/i2c/devices/i2c-16/$1"
+                         i2c_config "echo 24c02 0x50 > /sys/bus/i2c/devices/i2c-17/$1"
+                         ;;
+        "delete_device") i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-2/$1"
+                         i2c_config "echo 0x2c > /sys/bus/i2c/devices/i2c-7/$1"
+                         i2c_config "echo 0x49 > /sys/bus/i2c/devices/i2c-7/$1"
+                         i2c_config "echo 0x4a > /sys/bus/i2c/devices/i2c-7/$1"
+                         i2c_config "echo 0x4b > /sys/bus/i2c/devices/i2c-7/$1"
+                         i2c_config "echo 0x4c > /sys/bus/i2c/devices/i2c-7/$1"
+                         i2c_config "echo 0x4f > /sys/bus/i2c/devices/i2c-7/$1"
+                         i2c_config "echo 0x5e > /sys/bus/i2c/devices/i2c-10/$1"
+                         i2c_config "echo 0x5e > /sys/bus/i2c/devices/i2c-11/$1"
+                         i2c_config "echo 0x56 > /sys/bus/i2c/devices/i2c-10/$1"
+                         i2c_config "echo 0x56 > /sys/bus/i2c/devices/i2c-11/$1"
+                         i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-15/$1"
+                         i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-16/$1"
+                         i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-17/$1"
+                         ;;
+        *)               echo "n3248te_platform: main_board_mux : invalid command !"
+                         ;;
+    esac
+}
+
+#Attach/Detach the SFP modules on PCA9548_2
+switch_board_sfp() {
+    case $1 in
+        "new_device")    i2c_config "echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-20/$1"
+                         i2c_config "echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-21/$1"
+                         i2c_config "echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-22/$1"
+                         i2c_config "echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-23/$1"
+                         i2c_config "echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-24/$1"
+                         i2c_config "echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-25/$1"
+                         ;;
+        "delete_device") i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-20/$1"
+                         i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-21/$1"
+                         i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-22/$1"
+                         i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-23/$1"
+                         i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-24/$1"
+                         i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-25/$1"
+                         ;;
+        *)               echo "n3248te_platform: switch_board_sfp: invalid command !"
+                         ;;
+    esac
+}
+
+#Forcibly bring quad-port phy out of reset for 48-1G port functionality
+
+platform_firmware_versions() {
+
+FIRMWARE_VERSION_FILE=/var/log/firmware_versions
+rm -rf ${FIRMWARE_VERSION_FILE}
+# Get BIOS version
+echo "BIOS: `dmidecode -s system-version `" > $FIRMWARE_VERSION_FILE
+# Get CPU CPLD version
+echo "CPU CPLD: $((`cat /sys/devices/platform/dell-n3248te-cpld.0/cpu_cpld_mjr_ver`)).$((`cat /sys/devices/platform/dell-n3248te-cpld.0/cpu_cpld_mnr_ver`))" >> $FIRMWARE_VERSION_FILE
+# Get SYS CPLD version
+echo "SYS CPLD: $((`cat /sys/devices/platform/dell-n3248te-cpld.0/sys_cpld_mjr_ver`)).$((`cat /sys/devices/platform/dell-n3248te-cpld.0/sys_cpld_mnr_ver`))" >> $FIRMWARE_VERSION_FILE
+
+}
+
+install_python_api_package() {
+    device="/usr/share/sonic/device"
+    platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform)
+
+    pip3 install $device/$platform/sonic_platform-1.0-py3-none-any.whl
+}
+
+remove_python_api_package() {
+    rv=$(pip3 show sonic-platform > /dev/null 2>/dev/null)
+    if [ $? -eq 0 ]; then
+        rv=$(pip3 uninstall -y sonic-platform > /dev/null 2>/dev/null)
+    fi
+}
+
+get_reboot_cause() {
+    REBOOT_REASON_FILE="/host/reboot-cause/platform/reboot_reason"
+    mkdir -p $(dirname $REBOOT_REASON_FILE)
+
+    # Handle First Boot into software version with reboot cause determination support
+    if [[ ! -e $REBOOT_REASON_FILE ]]; then
+        echo "0x0" > $REBOOT_REASON_FILE
+    else
+        cat /sys/devices/platform/dell-n3248te-cpld.0/reboot_cause > $REBOOT_REASON_FILE
+    fi
+}
+
+
+if [[ "$1" == "init" ]]; then
+   modprobe i2c-dev
+   modprobe i2c-mux-pca954x force_deselect_on_exit=1
+   modprobe pmbus
+   modprobe emc2305
+   modprobe dps200
+   modprobe dell_n3248te_platform
+
+   sys_devices "new_device"
+   get_reboot_cause
+   switch_board_sfp "new_device"
+   echo 0xf0 > /sys/devices/platform/dell-n3248te-cpld.0/sfp_txdis
+   install_python_api_package
+   platform_firmware_versions
+elif [[ "$1" == "deinit" ]]; then
+    switch_board_sfp "delete_device"
+    sysdevices "delete_device"
+
+    modprobe -r dell_n3248te_platform
+
+    modprobe -r dps200
+    modprobe -r emc2305
+    modprobe -r pmbus
+    modprobe -r i2c-mux-pca954x
+    modprobe -r i2c-dev
+    remove_python_api_package
+else
+     echo "n3248te_platform : Invalid option !"
+fi
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/platform_sensors.py
new file mode 100755
index 000000000000..7756654a8219
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/platform_sensors.py
@@ -0,0 +1,139 @@
+#!/usr/bin/python
+# This provies support for the following objects:
+#   * Onboard temperature sensors
+#   * FAN trays
+#   * PSU
+
+
+import os
+import sys
+import logging
+import subprocess
+
+output = ""
+try:
+    rc = 0
+    output = subprocess.check_output('/usr/bin/sensors').splitlines()
+
+    valid = False
+    for line in output:
+        if line.startswith('acpitz') or line.startswith('coretemp'):
+            valid = True
+        if valid:
+            print line
+            if line == '': valid = False
+
+    print "Onboard Temperature Sensors:"
+    idx = 0
+    for line in output:
+        if line.startswith('tmp75'):
+            print '\t' + output[idx+2].split('(')[0]
+        idx += 1
+
+    print "\nFanTrays:"
+    idx = 0
+    found_emc = False
+    for line in output:
+        if line.startswith('emc'):
+            found_emc = True
+            with open('/sys/devices/platform/dell-n3248te-cpld.0/fan0_prs') as f:
+                line = f.readline()
+            present = int(line, 0)
+            if present :
+                print '\t' + 'FanTray1:'
+                print '\t\t' + 'Fan Speed:' + (output[idx+2].split('(')[0]).split(':')[1]
+                with open('/sys/devices/platform/dell-n3248te-cpld.0/fan0_dir') as f:
+                    line = f.readline()
+                dir = 'Intake' if line[:-1] == 'B2F' else 'Exhaust'
+                print '\t\t' + 'Airflow:\t' + dir
+            else : print '\t' + 'FanTray1:\tNot Present'
+
+            with open('/sys/devices/platform/dell-n3248te-cpld.0/fan1_prs') as f:
+                line = f.readline()
+            present = int(line, 0)
+            if present :
+                print '\t' + 'FanTray2:'
+                print '\t\t' + 'Fan Speed:' + (output[idx+3].split('(')[0]).split(':')[1]
+                with open('/sys/devices/platform/dell-n3248te-cpld.0/fan1_dir') as f:
+                    line = f.readline()
+                dir = 'Intake' if line[:-1] == 'B2F' else 'Exhaust'
+                print '\t\t' + 'Airflow:\t' + dir
+            else : print '\t' + 'FanTray2:\tNot Present'
+
+            with open('/sys/devices/platform/dell-n3248te-cpld.0/fan2_prs') as f:
+                line = f.readline()
+            present = int(line, 0)
+            if present :
+                print '\t' + 'FanTray3:'
+                print '\t\t' + 'Fan Speed:' + (output[idx+4].split('(')[0]).split(':')[1]
+                with open('/sys/devices/platform/dell-n3248te-cpld.0/fan2_dir') as f:
+                    line = f.readline()
+                dir = 'Intake' if line[:-1] == 'B2F' else 'Exhaust'
+                print '\t\t' + 'Airflow:\t' + dir
+            else : print '\t' + 'FanTray3:\tNot Present'
+        idx += 1
+    if not found_emc :
+        print '\t' + 'FanTray1:\tNot Present'
+        print '\t' + 'FanTray2:\tNot Present'
+        print '\t' + 'FanTray3:\tNot Present'
+
+    print '\nPSUs:'
+    idx = 0
+    with open('/sys/devices/platform/dell-n3248te-cpld.0/psu0_prs') as f:
+        line = f.readline()
+    found_psu1 = int(line, 0)
+    if not found_psu1 :
+        print '\tPSU1:\tNot Present'
+    with open('/sys/devices/platform/dell-n3248te-cpld.0/psu1_prs') as f:
+        line = f.readline()
+    found_psu2 = int(line, 0)
+    for line in output:
+        if line.startswith('dps460-i2c-10'):
+            with open('/sys/devices/platform/dell-n3248te-cpld.0/psu0_status') as f:
+                line = f.readline()
+            status = int(line, 0)
+            if not status :
+                print '\tPSU1:\tNot OK'
+                break
+            with open('/sys/bus/i2c/devices/10-0056/eeprom') as f:
+                line = f.readline()
+            dir = 'Exhaust' if 'FORWARD' in line else 'Intake'
+            print '\tPSU1:'
+            print '\t\t' + output[idx+2].split('(')[0]
+            print '\t\t' + output[idx+4].split('(')[0]
+            print '\t\t' + output[idx+6].split('(')[0]
+            print '\t\t' + output[idx+7].split('(')[0]
+            print '\t\t' + output[idx+9].split('(')[0]
+            print '\t\t' + output[idx+11].split('(')[0]
+            print '\t\t' + output[idx+12].split('(')[0]
+            print '\t\t' + output[idx+14].split('(')[0]
+            print '\t\t' + output[idx+15].split('(')[0]
+            print '\t\t' + 'Airflow:\t\t  ' + dir
+        if line.startswith('dps460-i2c-11'):
+            with open('/sys/devices/platform/dell-n3248te-cpld.0/psu1_status') as f:
+                line = f.readline()
+            status = int(line, 0)
+            if not status :
+                print '\tPSU2:\tNot OK'
+                break
+            print '\tPSU2:'
+            with open('/sys/bus/i2c/devices/11-0056/eeprom') as f:
+                line = f.readline()
+            dir = 'Exhaust' if 'FORWARD' in line else 'Intake'
+            print '\t\t' + output[idx+2].split('(')[0]
+            print '\t\t' + output[idx+4].split('(')[0]
+            print '\t\t' + output[idx+6].split('(')[0]
+            print '\t\t' + output[idx+7].split('(')[0]
+            print '\t\t' + output[idx+9].split('(')[0]
+            print '\t\t' + output[idx+11].split('(')[0]
+            print '\t\t' + output[idx+12].split('(')[0]
+            print '\t\t' + output[idx+14].split('(')[0]
+            print '\t\t' + output[idx+15].split('(')[0]
+            print '\t\t' + 'Airflow:\t\t  ' + dir
+        idx += 1
+    if not found_psu2 :
+        print '\tPSU2:\tNot Present'
+
+except subprocess.CalledProcessError as err:
+    print ("Exception when calling get_sonic_error -> %s\n" %(err))
+    rc = err.returncode
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/portiocfg.py b/platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/portiocfg.py
new file mode 100755
index 000000000000..10216af1d781
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/portiocfg.py
@@ -0,0 +1,106 @@
+#!/usr/bin/python
+# Copyright (c) 2015 Dell Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+#
+# THIS CODE IS PROVIDED ON AN  *AS IS* BASIS, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
+# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS
+# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
+#
+# See the Apache Version 2.0 License for specific language governing
+# permissions and limitations under the License.
+#Script to read/write the portio based registers
+
+import sys
+import os
+import getopt
+import struct
+
+resource='/dev/port'
+
+def usage():
+        ''' This is the Usage Method '''
+
+        print '\t\t portiocfg.py  --default'
+        print '\t\t portiocfg.py  --get --offset <offset>'
+        print '\t\t portiocfg.py --set --val <val>  --offset <offset>'
+        sys.exit(1)
+
+def portio_reg_read(resource,offset):
+    fd=os.open(resource, os.O_RDONLY)
+    if(fd<0):
+        print 'file open failed %s"%resource'
+        return
+    if(os.lseek(fd, offset, os.SEEK_SET) != offset):
+        print 'lseek failed on %s'%resource
+        return
+    buf=os.read(fd,1)
+    reg_val1=ord(buf)
+    print 'reg value %x'%reg_val1
+    os.close(fd)
+
+def portio_reg_write(resource,offset,val):
+    fd=os.open(resource,os.O_RDWR)
+    if(fd<0):
+        print 'file open failed %s"%resource'
+        return
+    if(os.lseek(fd, offset, os.SEEK_SET) != offset):
+        print 'lseek failed on %s'%resource
+        return
+    ret=os.write(fd,struct.pack('B',val))
+    if(ret != 1):
+        print 'write failed %d'%ret
+        return
+    os.close(fd)
+
+def main(argv):
+
+    ''' The main function will read the user input from the
+    command line argument and  process the request  '''
+
+    opts = ''
+    val = ''
+    choice = ''
+    resouce = ''
+    offset = ''
+
+    try:
+        opts, args = getopt.getopt(argv, "hgs:" , \
+        ["val=","offset=","help", "get", "set"])
+
+    except getopt.GetoptError:
+        usage()
+
+    for opt,arg in opts:
+
+        if opt in ('-h','--help'):
+            choice = 'help'
+
+        elif opt in ('-g', '--get'):
+            choice = 'get'
+
+        elif opt in ('-s', '--set'):
+            choice = 'set'
+
+        elif opt ==  '--offset':
+            offset = int(arg,16)
+
+        elif opt ==  '--val':
+            val = int(arg,16)
+
+    if choice == 'get' and offset != '':
+        portio_reg_read(resource,offset)
+
+    elif choice == 'set' and offset != '' and val != '':
+        portio_reg_write(resource,offset,val)
+
+    else:
+        usage()
+
+#Calling the main method
+if __name__ == "__main__":
+        main(sys.argv[1:])
+
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/ports_xcvrd_notify.py b/platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/ports_xcvrd_notify.py
new file mode 100755
index 000000000000..203d06e46cd3
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/ports_xcvrd_notify.py
@@ -0,0 +1,113 @@
+#!/usr/bin/env python3
+
+"""
+     port_notify
+     port notify status change for SONiC
+"""
+
+try:
+    import os
+    import sys
+    import time
+    from datetime import datetime
+    from swsscommon import swsscommon
+    from sonic_py_common import daemon_base, logger
+except ImportError as e:
+    raise ImportError (str(e) + " - required module not found")
+
+#
+# Constants ====================================================================
+#
+
+SYSLOG_IDENTIFIER = "port_notify"
+
+
+STATE_PORT_TABLE = 'PORT_TABLE'
+
+
+RJ45_PORT_START = 0;
+RJ45_PORT_END = 47;
+
+# Global logger class instance
+helper_logger = logger.Logger(SYSLOG_IDENTIFIER)
+
+XCVR_STATE_EMPTY   = 0
+XCVR_STATE_ERROR   = 1
+XCVR_STATE_INCOMP  = 2
+XCVR_STATE_CONFIG  = 3
+XCVR_STATE_READY   = 4
+XCVR_STATE_TIMEOUT = 5
+
+xcvr_state_tbl = {
+    XCVR_STATE_EMPTY:   { "xcvr_state": "N/A",          "xcvr_app_status": "down" },
+    XCVR_STATE_ERROR:   { "xcvr_state": "Error",        "xcvr_app_status": "down" },
+    XCVR_STATE_INCOMP:  { "xcvr_state": "Incompatible", "xcvr_app_status": "up" },
+    XCVR_STATE_CONFIG:  { "xcvr_state": "Config",       "xcvr_app_status": "down" },
+    XCVR_STATE_TIMEOUT: { "xcvr_state": "Timeout",      "xcvr_app_status": "up" },
+    XCVR_STATE_READY:   { "xcvr_state": "Ready",        "xcvr_app_status": "up" }
+}
+
+# Wait for port init is done
+def wait_for_port_init_done():
+    # Connect to APPL_DB and subscribe to PORT table notifications
+    appl_db = daemon_base.db_connect("APPL_DB")
+
+    sel = swsscommon.Select()
+    sst = swsscommon.SubscriberStateTable(appl_db, swsscommon.APP_PORT_TABLE_NAME)
+    sel.addSelectable(sst)
+
+    # Make sure this daemon started after all port configured
+    while True:
+        (state, c) = sel.select(1000)
+        if state == swsscommon.Select.TIMEOUT:
+            continue
+        if state != swsscommon.Select.OBJECT:
+            helper_logger.log_warning("sel.select() did not return swsscommon.Select.OBJECT")
+            continue
+
+        (key, op, fvp) = sst.pop()
+
+        # Wait until PortInitDone
+        if key in ["PortInitDone"]:
+            break
+
+def notify_port_xcvr_status(port_name, app_status_port_tbl, state_port_tbl, flag):
+
+    fvs = swsscommon.FieldValuePairs([("xcvr_status", xcvr_state_tbl[flag]["xcvr_app_status"])])
+    tm = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
+    state_fvs = swsscommon.FieldValuePairs([("xcvr_status", xcvr_state_tbl[flag]["xcvr_state"]), ("xcvr_time", tm)])
+
+    state_port_tbl.set(port_name, state_fvs)
+
+    app_status_port_tbl.set(port_name, fvs)
+
+    helper_logger.log_notice("Port {} xcvr_app_status change to {}".format(port_name, xcvr_state_tbl[flag]["xcvr_app_status"]))
+    return True
+
+
+def main():
+    helper_logger.log_notice("Start port_notify")
+    # Connect to APP_DB and create transceiver dom info table
+    appl_db = daemon_base.db_connect("APPL_DB")
+    cst = swsscommon.SubscriberStateTable(appl_db, swsscommon.APP_PORT_TABLE_NAME)
+
+    app_port_tbl = swsscommon.ProducerStateTable(appl_db, swsscommon.APP_PORT_TABLE_NAME)
+
+    app_status_port_tbl = swsscommon.ProducerStateTable(appl_db,
+                                                     swsscommon.APP_PORT_APP_STATUS_TABLE_NAME)
+
+    state_db = daemon_base.db_connect("STATE_DB")
+    state_port_tbl = swsscommon.Table(state_db, STATE_PORT_TABLE)
+
+    # Wait for PortInitDone
+    wait_for_port_init_done()
+
+    for port in range(RJ45_PORT_START, RJ45_PORT_END+1):
+        #print("Ethernet{}".format(port))
+        notify_port_xcvr_status("Ethernet{}".format(port), app_status_port_tbl, state_port_tbl, XCVR_STATE_READY)
+
+    helper_logger.log_notice("End port_notify")
+
+
+if __name__ == '__main__':
+    main()
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/sensors b/platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/sensors
new file mode 100755
index 000000000000..572b9d45e9e3
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/sensors
@@ -0,0 +1,8 @@
+#!/bin/bash
+#docker exec -i pmon sensors "$@"
+docker exec -i pmon /usr/bin/platform_sensors.py "$@"
+
+#To probe sensors not part of lm-sensors
+#if [ -r /usr/local/bin/platform_sensors.py ]; then
+#        python /usr/local/bin/platform_sensors.py
+#fi
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/setup.py b/platform/broadcom/sonic-platform-modules-dell/n3248te/setup.py
new file mode 120000
index 000000000000..4f6de9941d96
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/setup.py
@@ -0,0 +1 @@
+../s6100/setup.py
\ No newline at end of file
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/__init__.py
new file mode 100644
index 000000000000..3e1260e6b854
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/__init__.py
@@ -0,0 +1,8 @@
+"""
+Module sonic_platform provides the platform dependent population of
+platform.py, chassis.py, component.py, sfp.py, thermal.py, psu.py,
+fan.py and watchdog.py
+"""
+__all__ = ["platform", "chassis", "sfp", "eeprom", "component", "thermal", "psu", "fan", "fan_drawer", "watchdog"]
+from sonic_platform import *
+
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/chassis.py
new file mode 100644
index 000000000000..e060f8028319
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/chassis.py
@@ -0,0 +1,351 @@
+#!/usr/bin/env python
+
+#############################################################################
+# DELLEMC N3248TE
+#
+# Module contains an implementation of SONiC Platform Base API and
+# provides the platform information
+#
+#############################################################################
+
+try:
+    import os
+    import select
+    import sys
+    import time
+    from sonic_platform_base.chassis_base import ChassisBase
+    from sonic_platform.sfp import Sfp
+    from sonic_platform.eeprom import Eeprom
+    from sonic_platform.component import Component
+    from sonic_platform.psu import Psu
+    from sonic_platform.thermal import Thermal
+    from sonic_platform.watchdog import Watchdog
+    from sonic_platform.fan import Fan
+    from sonic_platform.fan_drawer import FanDrawer
+except ImportError as e:
+    raise ImportError(str(e) + "- required module not found")
+
+
+MAX_N3248TE_FANTRAY = 3
+MAX_N3248TE_FAN = 1
+MAX_N3248TE_PSU = 2
+MAX_N3248TE_THERMAL = 5
+MAX_N3248TE_COMPONENT = 3 # BIOS, CPU CPLD and SYS CPLD
+
+media_part_num_list = set([ \
+"8T47V","XTY28","MHVPK","GF76J","J6FGD","F1KMV","9DN5J","H4DHD","6MCNV","0WRX0","X7F70","5R2PT","WTRD1","WTRD1","WTRD1","WTRD1","5250G","WTRD1","C5RNH","C5RNH","FTLX8571D3BCL-FC",
+"C5RNH","5250G","N8TDR","7D64H","7D64H","RN84N","RN84N","HMTNW","6K3Y6","6K3Y6","TY5FM","50M0R","PGYJT","WP2PP","85Y13","1HCGH","FP9R1","FYD0M","C6Y7M","C6Y7M","V250M","V250M",
+"5CWK6","5CWK6","53HVN","53HVN","358VV","358VV","MV799","MV799","YJF03","P9GND","T1KCN","1DXKP","MT7R2","K0T7R","W5G04","7TCDN","7TCDN","7TCDN","7TCDN","7TCDN","V3XJK","0MV31",
+"5FVP7","N6KM9","C41MF","77KC3","XW7J0","V4NJV","2XJHY","H93DH","H93DH","F8CG0","F8CG0","F8CG0","119N6","WFMF5","794RX","288F6","1M31V","1M31V","5NP8R","5NP8R","4TC09","4TC09",
+"FC6KV","FC6KV","J90VN","J90VN","05RH0","05RH0","YDN52","0C2YV","YDN52","0C2YV","9JT65","D7M6H","6GW14","FYVFW","0VF5H","P4YPY","P4YPY","TCPM2","TCPM2","JNPF8","JNPF8","27GG5",
+"27GG5","P8T4W","P8T4W","JR54Y","M6N0J","XJYD0","K44H9","035KG","P7C7N","76V43","3CC35","FN4FC","26FN3","YFNDD","YFNDD","7R9N9","035KG","P7C7N","76V43","3CC35","PLRXPLSCS43811",
+"FN4FC","26FN3","YFNDD","YFNDD","7R9N9","G86YJ","V407F","V407F","9KH6T","G86YJ","V407F","9KH6T","2JVDD","D0R73","VXFJY","9X8JP","2JVDD","D0R73","VXFJY","9X8JP","2JVDD","D0R73","VXFJY",
+"9X8JP","GMFC5","GMFC5","GMFC5","D7P80","3MFXG","3MFXG","0GWXJ","THPF3","THPF3","THPF3","THPF3","THPF3","PJ62G","3XCX1","JJYKG","RRRTK","16K56","86JM2","K5R6C","7MG2C","WTPPN","9HTT2",
+"NKM4F","VXGGG","JC9W6","6MR8M","RP3GV","M5PPJ","XKY55","TKCXT","05J8P","5WGKD","XFDRT","NW8DM","YPKH3","5WGKD","XFDRT","NW8DM","YPKH3","71XXK","MVCX6","0XYP6","HPPVW","3GHRT","71XXK",
+"MVCX6","0XYP6","HPPVW","3GHRT","2X5T6","135V2","KD5MV","2X5T6","KD5MV","HHFK0","3YWG7","5CMT2","RCVP5","X5DH4","HHFK0","3YWG7","5CMT2","RCVP5","X5DH4","3YWG7","5CMT2","RCVP5","X5DH4",
+"4WJ41","4WJ41","14NV5","14NV5","14NV5","4WGYD","YKMH7","X7CCC","X7CCC","0X9CT","0CY8V","P7D7R","W4GPP","W4GPP","W4GPP","HHHCHC","07RN7","07RN7","0YR96","0YR96","JCYM9","FTLX8571D3BCL",
+"DDW0X","VPFDJ","229KM","9FC7D","DDW0X","VPFDJ","6FMR5","J7K20","N3K9W","6FMR5","8R4VM","7VN5T","D9YM8","8R4VM","VYXPW","87TPX","WY6FK","VYXPW","87TPX","WY6FK","WG8C4","N8K82","2DV6Y",
+"77C3C","RC0HM","77C3C","RC0HM","JHXTN","3P3PG","92YVM","4VX5M","4VX5M","6RRGD","W4JWV","22V6R","XR11M","9GMDY","JMCWK","TP2F0","6MGDY","78RHK", "C0TP5","0WDNV","FCLF8522P2BTL"\
+])
+class Chassis(ChassisBase):
+    """
+    DELLEMC Platform-specific Chassis class
+    """
+    CPLD_DIR = '/sys/devices/platform/dell-n3248te-cpld.0/'
+
+    _global_port_pres_dict = {}
+
+    _sfpp_port_to_i2c_mapping = {
+            49: 20,
+            50: 21,
+            51: 22,
+            52: 23,
+            53: 24,
+            54: 25,
+            }
+
+    def __init__(self):
+        ChassisBase.__init__(self)
+        # sfp.py will read eeprom contents and retrive the eeprom data.
+        # We pass the eeprom path from chassis.py
+        self.PORT_START = 1
+        self.PORT_END = 54
+        self.PORTS_IN_BLOCK = (self.PORT_END + 1)
+        self.SFP_PORT_START = 49
+        self._sfp_port = range(self.SFP_PORT_START, self.PORTS_IN_BLOCK)
+        eeprom_base = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom"
+        for index in range(self.PORT_START, self.PORTS_IN_BLOCK):
+            eeprom_path = ''
+            if index in self._sfp_port:
+                eeprom_path = eeprom_base.format(self._sfpp_port_to_i2c_mapping[index])
+            if(index < 53):
+                port_type = 'SFP'
+            else:
+                port_type = 'QSFP'
+
+            sfp_node = Sfp(index, port_type, eeprom_path)
+            self._sfp_list.append(sfp_node)
+
+        self._eeprom = Eeprom()
+        self._watchdog = Watchdog()
+        self._num_sfps = 54
+        self._num_fans =  MAX_N3248TE_FANTRAY * MAX_N3248TE_FAN
+        self._fan_list = [Fan(i, j) for i in range(MAX_N3248TE_FANTRAY) \
+                            for j in range(MAX_N3248TE_FAN)]
+        for k in range(MAX_N3248TE_FANTRAY):
+            fandrawer = FanDrawer(k)
+            self._fan_drawer_list.append(fandrawer)
+            self._fan_list.extend(fandrawer._fan_list)
+
+        self._psu_list = [Psu(i) for i in range(MAX_N3248TE_PSU)]
+        self._thermal_list = [Thermal(i) for i in range(MAX_N3248TE_THERMAL)]
+        self._component_list = [Component(i) for i in range(MAX_N3248TE_COMPONENT)]
+        for port_num in self._sfp_port:
+            # sfp get uses zero-indexing, but port numbers start from 1
+            presence = self.get_sfp(port_num-1).get_presence()
+            self._global_port_pres_dict[port_num] = '1' if presence else '0'
+
+        self._watchdog = Watchdog()
+        self.locator_led_reg = "locator_led"
+        self.LOCATOR_LED_ON = "blink_blue"
+        self.LOCATOR_LED_OFF = self.STATUS_LED_COLOR_OFF
+
+    def _get_cpld_register(self, reg_name):
+        # On successful read, returns the value read from given
+        # reg name and on failure rethrns 'ERR'
+        cpld_reg_file = self.CPLD_DIR + '/' + reg_name
+        try:
+            rv = open(cpld_reg_file, 'r').read()
+        except IOError : return 'ERR'
+        return rv.strip('\r\n').lstrip(' ')
+
+    def _set_cpld_register(self, reg_name, value):
+        # On successful write, returns the value will be written on
+        # reg_name and on failure returns 'ERR'
+        rv = 'ERR'
+        cpld_reg_file = self.CPLD_DIR + '/' + reg_name
+
+        if (not os.path.isfile(cpld_reg_file)):
+            #print "open error"
+            return rv
+
+        try:
+           with open(cpld_reg_file, 'w') as fd:
+                rv = fd.write(str(value))
+        except:
+            rv = 'ERR'
+
+        return rv
+
+# check for this event change for sfp / do we need to handle timeout/sleep
+
+    def get_change_event(self, timeout=0):
+        """
+        Returns a nested dictionary containing all devices which have
+        experienced a change at chassis level
+        """
+        port_dict = {}
+        change_dict = {}
+        change_dict['sfp'] = port_dict
+        while True:
+            for port_num in self._sfp_port:
+                # sfp get uses zero-indexing, but port numbers start from 1
+                presence = self.get_sfp(port_num-1).get_presence()
+                if(presence and self._global_port_pres_dict[port_num] == '0'):
+                    self._global_port_pres_dict[port_num] = '1'
+                    port_dict[port_num] = '1'
+                elif(not presence and self._global_port_pres_dict[port_num] == '1'):
+                    self._global_port_pres_dict[port_num] = '0'
+                    port_dict[port_num] = '0'
+
+                if(len(port_dict) > 0):
+                    return True, change_dict
+
+            time.sleep(0.5)
+
+
+
+    def get_sfp(self, index):
+        """
+        Retrieves sfp represented by (0-based) index <index>
+
+        Args:
+            index: An integer, the index (0-based) of the sfp to retrieve.
+                   The index should be the sequence of a physical port in a chassis,
+                   starting from 0.
+                   For example, 0 for Ethernet0, 1 for Ethernet4 and so on.
+
+        Returns:
+            An object dervied from SfpBase representing the specified sfp
+        """
+        sfp = None
+
+        try:
+            # The index will start from 0
+            sfp = self._sfp_list[index-1]
+        except IndexError:
+            sys.stderr.write("SFP index {} out of range (1-{})\n".format(
+                             index, len(self._sfp_list)))
+        return sfp
+
+    def get_name(self):
+        """
+        Retrieves the name of the chassis
+        Returns:
+           string: The name of the chassis
+        """
+        return self._eeprom.modelstr().decode()
+
+    def get_presence(self):
+        """
+        Retrieves the presence of the chassis
+        Returns:
+            bool: True if chassis is present, False if not
+        """
+        return True
+
+    def get_model(self):
+        """
+        Retrieves the model number (or part number) of the chassis
+        Returns:
+            string: Model/part number of chassis
+        """
+        return self._eeprom.part_number_str()
+
+    def get_serial(self):
+        """
+        Retrieves the serial number of the chassis (Service tag)
+        Returns:
+            string: Serial number of chassis
+        """
+        return self._eeprom.serial_str()
+
+    def get_status(self):
+        """
+        Retrieves the operational status of the chassis
+        Returns:
+            bool: A boolean value, True if chassis is operating properly
+            False if not
+        """
+        return True
+
+    def get_base_mac(self):
+        """
+        Retrieves the base MAC address for the chassis
+        Returns:
+            A string containing the MAC address in the format
+            'XX:XX:XX:XX:XX:XX'
+        """
+        return self._eeprom.base_mac_addr('')
+
+    def get_serial_number(self):
+        """
+        Retrieves the hardware serial number for the chassis
+        Returns:
+            A string containing the hardware serial number for this chassis.
+        """
+        return self._eeprom.serial_number_str()
+
+    def get_system_eeprom_info(self):
+        """
+        Retrieves the full content of system EEPROM information for the chassis
+        Returns:
+            A dictionary where keys are the type code defined in
+            OCP ONIE TlvInfo EEPROM format and values are their corresponding
+            values.
+        """
+        return self._eeprom.system_eeprom_info()
+
+    def get_reboot_cause(self):
+        """
+        Retrieves the cause of the previous reboot
+        Returns:
+            A tuple (string, string) where the first element is a string
+            containing the cause of the previous reboot. This string must be
+            one of the predefined strings in this class. If the first string
+            is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used
+            to pass a description of the reboot cause.
+        """
+
+        reset_reason = int(self._get_cpld_register('reboot_cause'), 16)
+
+        if (reset_reason & 0x02) :
+            return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, 'Shutdown by CPU')
+        elif (reset_reason & 0x04) :
+            return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, "Failed to boot from configured boot device")
+        elif (reset_reason & 0x8) :
+            return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, "Booted from Backup BIOS")
+        elif (reset_reason & 0x10) :
+            return(ChassisBase.REBOOT_CAUSE_WATCHDOG, None)
+        elif (reset_reason & 0x20):
+            return(ChassisBase.REBOOT_CAUSE_THERMAL_OVERLOAD_CPU)
+        elif (reset_reason & 0x40) :
+            return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, 'Warm Reset')
+        elif (reset_reason & 0x80) :
+            return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, 'Cold Reset')
+        elif (reset_reason & 0x01) :
+            return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None)
+
+    def get_eeprom(self):
+        """
+        Retrieves the Sys Eeprom instance for the chassis.
+        Returns :
+            The instance of the Sys Eeprom
+        """
+        return self._eeprom
+
+    def get_num_fans(self):
+        """
+        Retrives the number of Fans on the chassis.
+        Returns :
+            An integer represents the number of Fans on the chassis.
+        """
+        return self._num_fans
+
+    def get_num_sfps(self):
+        """
+        Retrives the numnber of Media on the chassis.
+        Returns:
+            An integer represences the number of SFPs on the chassis.
+        """
+        return self._num_sfps
+
+    def get_qualified_media_list(self):
+        return media_part_num_list
+
+    def set_locator_led(self, color):
+        """
+        Sets the state of the Chassis Locator LED
+
+        Args:
+            color: A string representing the color with which to set the Chassis Locator LED
+
+        Returns:
+            bool: True if the Chassis Locator LED state is set successfully, False if not
+
+        """
+        if color == self.LOCATOR_LED_ON or color == self.LOCATOR_LED_OFF:
+            rv = self._set_cpld_register(self.locator_led_reg, color)
+            if (rv != 'ERR'):
+                return True
+        else:
+            return False
+
+    def get_locator_led(self):
+        """
+        Gets the state of the Chassis Locator LED
+
+        Returns:
+            LOCATOR_LED_ON or LOCATOR_LED_OFF
+        """
+        loc_led = self._get_cpld_register(self.locator_led_reg)
+        if (loc_led != 'ERR'):
+            # Actually driver returns the color code 'blink_blue'
+            # Returning "blue_blink" to make it common to all platforms output
+            if (loc_led == self.LOCATOR_LED_ON):
+                self.LOCATOR_LED_ON = self.STATUS_LED_COLOR_BLUE_BLINK
+                return self.LOCATOR_LED_ON
+            else:
+                return self.LOCATOR_LED_OFF
+        else:
+            return self.LOCATOR_LED_OFF
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/component.py
new file mode 100644
index 000000000000..0fd3d8084da6
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/component.py
@@ -0,0 +1,84 @@
+#!/usr/bin/env python
+
+########################################################################
+# DELLEMC N3248TE
+#
+# Module contains an implementation of SONiC Platform Base API and
+# provides the Components' (e.g., BIOS, CPLD, FPGA, BMC etc.) available in
+# the platform
+#
+########################################################################
+
+try:
+    import os
+    import re
+    import subprocess
+    from sonic_platform_base.component_base import ComponentBase
+
+except ImportError as e:
+    raise ImportError(str(e) + "- required module not found")
+def get_bios_version():
+    return subprocess.check_output(['dmidecode', '-s', 'system-version']).strip().decode()
+
+def get_cpld_version(cpld):
+    mjr_ver=subprocess.check_output('cat /sys/devices/platform/dell-n3248te-cpld.0/' + cpld + '_mjr_ver', shell=True).strip()[2:].decode()
+    mnr_ver=subprocess.check_output('cat /sys/devices/platform/dell-n3248te-cpld.0/' + cpld + '_mnr_ver', shell=True).strip()[2:].decode()
+    return (str(mjr_ver) + '.' + str(mnr_ver))
+
+class Component(ComponentBase):
+    """DellEMC Platform-specific Component class"""
+
+    CHASSIS_COMPONENTS = [
+        ['BIOS',
+         'Performs initialization of hardware components during booting',
+         get_bios_version()
+        ],
+        ['CPU CPLD',
+         'Used for managing the CPU power sequence and CPU states',
+         get_cpld_version('cpu_cpld')
+        ],
+        ['SYS CPLD',
+         'Used for managing FAN, PSU, SFP modules (1-48) SFP Plus modules (49-62)',
+         get_cpld_version('sys_cpld')
+        ]
+    ]
+
+    def __init__(self, component_index=0):
+        self.index = component_index
+        self.name = self.CHASSIS_COMPONENTS[self.index][0]
+        self.description = self.CHASSIS_COMPONENTS[self.index][1]
+        self.version = self.CHASSIS_COMPONENTS[self.index][2]
+
+    def get_name(self):
+        """
+        Retrieves the name of the component
+        Returns:
+        A string containing the name of the component
+        """
+        return self.name
+
+    def get_description(self):
+        """
+        Retrieves the description of the component
+        Returns:
+        A string containing the description of the component
+        """
+        return self.description
+
+    def get_firmware_version(self):
+        """
+        Retrieves the firmware version of the component
+        Returns:
+            A string containing the firmware version of the component
+        """
+        return self.version
+
+    def install_firmware(self, image_path):
+        """
+        Installs firmware to the component
+        Args:
+        image_path: A string, path to firmware image
+        Returns:
+        A boolean, True if install was successful, False if not
+        """
+        return False
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/eeprom.py
new file mode 100644
index 000000000000..d2dc2f723108
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/eeprom.py
@@ -0,0 +1,134 @@
+#!/usr/bin/env python
+
+#############################################################################
+# DellEmc Z9332F
+#
+# Platform and model specific eeprom subclass, inherits from the base class,
+# and provides the followings:
+# - the eeprom format definition
+# - specific encoder/decoder if there is special need
+#############################################################################
+try:
+    import os.path
+    from sonic_eeprom import eeprom_tlvinfo
+    import binascii
+except ImportError as e:
+    raise ImportError(str(e) + "- required module not found")
+
+
+class Eeprom(eeprom_tlvinfo.TlvInfoDecoder):
+
+    def __init__(self):
+        self.eeprom_path = None
+        f = '/sys/class/i2c-adapter/i2c-2/2-0050/eeprom'
+        if not os.path.exists(f):
+            return
+        self.eeprom_path = f
+        super(Eeprom, self).__init__(self.eeprom_path, 0, '', True)
+        self.eeprom_tlv_dict = dict()
+        try:
+            self.eeprom_data = self.read_eeprom()
+        except:
+            self.eeprom_data = "N/A"
+            raise RuntimeError("Eeprom is not Programmed")
+
+        eeprom = self.eeprom_data
+
+        if not self.is_valid_tlvinfo_header(eeprom):
+            return
+
+        total_length = ((eeprom[9]) << 8) | (eeprom[10])
+        tlv_index = self._TLV_INFO_HDR_LEN
+        tlv_end = self._TLV_INFO_HDR_LEN + total_length
+
+        while (tlv_index + 2) < len(eeprom) and tlv_index < tlv_end:
+            if not self.is_valid_tlv(eeprom[tlv_index:]):
+                break
+
+            tlv = eeprom[tlv_index:tlv_index + 2
+                         + (eeprom[tlv_index + 1])]
+            code = "0x%02X" % ((tlv[0]))
+
+
+            name, value = self.decoder(None, tlv)
+
+            self.eeprom_tlv_dict[code] = value
+            if (eeprom[tlv_index]) == self._TLV_CODE_CRC_32:
+                break
+
+            tlv_index += (eeprom[tlv_index+1]) + 2
+
+    def serial_number_str(self):
+        """
+        Returns the serial number
+        """
+        (is_valid, results) = self.get_tlv_field(
+                         self.eeprom_data, self._TLV_CODE_SERIAL_NUMBER)
+        if not is_valid:
+            return "N/A"
+        return results[2].decode('ascii')
+
+    def base_mac_addr(self, e):
+        """
+        Returns the base mac address found in the system EEPROM
+        """
+        (is_valid, t) = self.get_tlv_field(
+                          self.eeprom_data, self._TLV_CODE_MAC_BASE)
+        if not is_valid or t[1] != 6:
+            return super(eeprom_tlvinfo.TlvInfoDecoder, self).switchaddrstr(t)
+
+        return ":".join([binascii.b2a_hex(T) for T in t[2]])
+
+    def modelstr(self):
+        """
+        Returns the Model name
+        """
+        (is_valid, results) = self.get_tlv_field(
+                        self.eeprom_data, self._TLV_CODE_PRODUCT_NAME)
+        if not is_valid:
+            return "N/A"
+
+        return results[2]
+
+    def part_number_str(self):
+        """
+        Returns the part number
+        """
+        (is_valid, results) = self.get_tlv_field(
+                    self.eeprom_data, self._TLV_CODE_PART_NUMBER)
+        if not is_valid:
+            return "N/A"
+
+        return results[2]
+
+    def serial_str(self):
+        """
+        Returns the servicetag number
+        """
+        (is_valid, results) = self.get_tlv_field(
+                    self.eeprom_data, self._TLV_CODE_SERVICE_TAG)
+        if not is_valid:
+            return "N/A"
+
+        return results[2]
+
+    def revision_str(self):
+        """
+        Returns the device revision
+        """
+        (is_valid, results) = self.get_tlv_field(
+                    self.eeprom_data, self._TLV_CODE_DEVICE_VERSION)
+        if not is_valid:
+            return "N/A"
+
+        return results[2]
+
+    def system_eeprom_info(self):
+        """
+        Returns a dictionary, where keys are the type code defined in
+        ONIE EEPROM format and values are their corresponding values
+        found in the system EEPROM.
+        """
+        return self.eeprom_tlv_dict
+
+
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/fan.py
new file mode 100644
index 000000000000..0b23a5564790
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/fan.py
@@ -0,0 +1,169 @@
+#!/usr/bin/env python
+
+########################################################################
+# DellEMC Z9332F
+#
+# Module contains an implementation of SONiC Platform Base API and
+# provides the Fans' information which are available in the platform.
+#
+########################################################################
+try:
+    import os
+    from sonic_platform_base.fan_base import FanBase
+except ImportError as e:
+    raise ImportError(str(e) + "- required module not found")
+
+
+class Fan(FanBase):
+    """DellEMC Platform-specific Fan class"""
+
+    def __init__(self, fantray_index=0, fan_index=0, psu_fan=False, dependency=None):
+        self.is_psu_fan = psu_fan
+
+        if not self.is_psu_fan:
+            # API index is starting from 0, DellEMC platform index is
+            # starting from 1
+            self.presence_reg = "fan{}_prs".format(fantray_index)
+            self.dir_reg = "fan{}_dir".format(fantray_index)
+            self.rpm_file = "/sys/bus/i2c/devices/7-002c/fan{}_input".format(fantray_index+1)
+            self.eeprom = "/sys/bus/i2c/devices/{}-0050/eeprom".format(15 + fantray_index)
+            self.fantray_index = fantray_index
+        else:
+            self.presence_reg = "psu{}_prs".format(fantray_index)
+            self.psu_index = fantray_index
+            self.dependancy = dependency
+            self.dir_reg = ""
+            self.dps_hwmon = "/sys/bus/i2c/devices/{}-005e/hwmon/".format(fantray_index+10)
+            self.eeprom = "/sys/bus/i2c/devices/{}-0056/eeprom".format(10 + fantray_index)
+        self.max_speed = 0
+
+    def _get_cpld_register(self, reg_name):
+        # On successful read, returns the value read from given
+        # reg name and on failure rethrns 'ERR'
+        cpld_dir = "/sys/devices/platform/dell-n3248te-cpld.0/"
+        cpld_reg_file = cpld_dir + '/' + reg_name
+        try:
+            buf = open(cpld_reg_file, 'r').read()
+        except (IOError, AttributeError):
+            return 'ERR'
+        return buf.strip('\r\n').lstrip(' ')
+
+    def get_name(self):
+        """
+        Retrieves the name of the device
+        Returns:
+            String: The name of the device
+        """
+        if self.is_psu_fan:
+            return "PSU{} Fan".format(self.psu_index)
+        else:
+            return "Fan{}".format(self.fantray_index+1)
+
+    def get_model(self):
+        """
+        Retrieves the part number of the FAN
+        Returns:
+            String: Part number of FAN
+        """
+        try:
+            val = open(self.eeprom, "rb").read()[13:19]
+        except:
+            val = None
+        return val.decode()
+
+    def get_serial(self):
+        """
+        Retrieves the serial number of the FAN
+        Returns:
+            String: Serial number of FAN
+        """
+        try:
+            val = open(self.eeprom, "rb").read()[21:41]
+        except:
+            val = None
+        return val.decode()
+
+    def get_presence(self):
+        """
+        Retrieves the presence of the FAN
+        Returns:
+            bool: True if fan is present, False if not
+        """
+
+        presence = self._get_cpld_register(self.presence_reg)
+        if presence == 'ERR':
+            return False
+        if int(presence,0) == 1:
+            return True
+
+    def get_status(self):
+        """
+        Retrieves the operational status of the FAN
+        Returns:
+            bool: True if FAN is operating properly, False if not
+        """
+        return True
+
+    def get_direction(self):
+        """
+        Retrieves the fan airfow direction
+        Returns:
+            A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST
+            depending on fan direction
+
+        Notes:
+            In DellEMC platforms,
+            - Forward/Exhaust : Air flows from Port side to Fan side.
+            - Reverse/Intake  : Air flows from Fan side to Port side.
+        """
+        if not self.is_psu_fan:
+            val = self._get_cpld_register(self.dir_reg)
+            direction = 'Exhaust' if val == 'F2B' else 'Intake'
+            if direction == 'ERR':
+                return None
+        else:
+            try:
+                val = open(self.eeprom, "rb").read()[0xe1:0xe8]
+            except:
+                return None
+            direction = 'Exhaust' if val == 'FORWARD' else 'Intake'
+        return direction
+
+    def get_speed(self):
+        """
+        Retrieves the speed of the fan
+        Returns:
+            int: percentage of the max fan speed
+        """
+        if self.max_speed == 0:
+            self.max_speed = 23500
+        fan_speed = 0
+        try:
+            if not self.is_psu_fan:
+                rpm_file = self.rpm_file
+            else:
+                dps_dir = self.dps_hwmon + '/' + os.listdir(self.dps_hwmon)[0]
+                rpm_file = dps_dir + '/' + 'fan1_input'
+            fan_speed = int(open(rpm_file, "rb").read())
+        except:
+            return None
+        speed = (100 * fan_speed)//self.max_speed
+        return speed
+
+    def get_speed_rpm(self):
+        """
+        Retrieves the speed of the fan
+        Returns:
+            int: percentage of the max fan speed
+        """
+        fan_speed = 0
+        try:
+            if not self.is_psu_fan:
+                rpm_file = self.rpm_file
+            else:
+                dps_dir = self.dps_hwmon + '/' + os.listdir(self.dps_hwmon)[0]
+                rpm_file = dps_dir + '/' + 'fan1_input'
+            fan_speed = int(open(rpm_file, "rb").read())
+        except:
+            return None
+        return fan_speed
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/fan_drawer.py
new file mode 100644
index 000000000000..5142827554db
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/fan_drawer.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+
+########################################################################
+# DellEMC N3248TE
+#
+# Module contains an implementation of SONiC Platform Base API and
+# provides the Fan-Drawers' information available in the platform.
+#
+########################################################################
+
+try:
+    from sonic_platform_base.fan_drawer_base import FanDrawerBase
+    from sonic_platform.fan import Fan
+except ImportError as e:
+    raise ImportError(str(e) + "- required module not found")
+
+N3248TE_FANS_PER_FANTRAY = 2
+
+
+class FanDrawer(FanDrawerBase):
+    """DellEMC Platform-specific Fan class"""
+
+    def __init__(self, fantray_index):
+
+        FanDrawerBase.__init__(self)
+        # FanTray is 1-based in DellEMC platforms
+        self.fantrayindex = fantray_index + 1
+        for i in range(N3248TE_FANS_PER_FANTRAY):
+            self._fan_list.append(Fan(fantray_index, i))
+
+    def get_name(self):
+        """
+        Retrieves the fan drawer name
+        Returns:
+            string: The name of the device
+        """
+        return "FanTray{}".format(self.fantrayindex)
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/platform.py
new file mode 100644
index 000000000000..996d94cf5a6e
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/platform.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+
+#############################################################################
+#
+# Module contains an implementation of SONiC Platform Base API and
+# provides the platform information
+#
+#############################################################################
+
+try:
+    from sonic_platform_base.platform_base import PlatformBase
+    from sonic_platform.chassis import Chassis
+except ImportError as e:
+    raise ImportError(str(e) + "- required module not found")
+
+
+class Platform(PlatformBase):
+    """
+    DELLEMC Platform-specific class
+    """
+
+    def __init__(self):
+        PlatformBase.__init__(self)
+        self._chassis = Chassis()
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/psu.py
new file mode 100644
index 000000000000..fb4167e67da7
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/psu.py
@@ -0,0 +1,204 @@
+#!/usr/bin/env python
+
+########################################################################
+# DellEMC Z9332F
+#
+# Module contains an implementation of SONiC Platform Base API and
+# provides the PSUs' information which are available in the platform
+#
+########################################################################
+
+try:
+    import os
+    from sonic_platform_base.psu_base import PsuBase
+    from sonic_platform.fan import Fan
+except ImportError as e:
+    raise ImportError(str(e) + "- required module not found")
+
+
+class Psu(PsuBase):
+    """DellEMC Platform-specific PSU class"""
+
+    def __init__(self, psu_index):
+        PsuBase.__init__(self)
+        self.index = psu_index + 1 # PSU is 1-based in DellEMC platforms
+        self.psu_presence_reg = "psu{}_prs".format(psu_index)
+        self.psu_status = "psu{}_status".format(psu_index)
+        self.eeprom = "/sys/bus/i2c/devices/{}-0056/eeprom".format(10+psu_index)
+        self.psu_voltage_reg = 'in3_input'
+        self.psu_current_reg = 'curr2_input'
+        self.psu_power_reg = 'power2_input'
+        self.dps_hwmon = "/sys/bus/i2c/devices/{}-005e/hwmon/".format(10 + psu_index)
+        self.dps_hwmon_exist = os.path.exists(self.dps_hwmon)
+        self._fan_list.append(Fan(fan_index=self.index, psu_fan=True, dependency=self))
+
+    def _get_cpld_register(self, reg_name):
+        # On successful read, returns the value read from given
+        # reg name and on failure rethrns 'ERR'
+        cpld_dir = "/sys/devices/platform/dell-n3248te-cpld.0/"
+        cpld_reg_file = cpld_dir + '/' + reg_name
+        try:
+            rv = open(cpld_reg_file, 'r').read()
+        except IOError : return 'ERR'
+        return rv.strip('\r\n').lstrip(' ')
+
+    def _get_dps_register(self, reg_name):
+        try :
+            dps_dir = self.dps_hwmon + '/' + os.listdir(self.dps_hwmon)[0]
+            dps_reg_file = dps_dir + '/' + reg_name
+            rv = open(dps_reg_file, 'r').read()
+        except (IOError, OSError) : return 'ERR'
+        return rv
+
+    def get_name(self):
+        """
+        Retrieves the name of the device
+
+        Returns:
+            string: The name of the device
+        """
+        return "PSU{}".format(self.index)
+
+    def _reload_dps_module(self):
+        try:
+            del_cmd = "echo  0x56 > /sys/bus/i2c/devices/i2c-{}/delete_device".format(10 + self.index - 1)
+            os.system(del_cmd)
+        except (IOError, OSError):
+            pass
+        try:
+            del_cmd = "echo  0x5e > /sys/bus/i2c/devices/i2c-{}/delete_device".format(10 + self.index - 1)
+            os.system(del_cmd)
+        except (IOError, OSError):
+            pass
+        try:
+            ins_cmd = "echo '24c02 0x56' > /sys/bus/i2c/devices/i2c-{}/new_device".format(10 + self.index - 1)
+            os.system(ins_cmd)
+            ins_cmd = "echo 'dps460 0x5e' > /sys/bus/i2c/devices/i2c-{}/new_device".format(10 + self.index - 1)
+            os.system(ins_cmd)
+        except (IOError, OSError):
+            pass
+
+    def get_presence(self):
+        """
+        Retrieves the presence of the Power Supply Unit (PSU)
+
+        Returns:
+            bool: True if PSU is present, False if not
+        """
+        presence = self._get_cpld_register(self.psu_presence_reg).strip()
+        if presence == 'ERR' : return False
+        if not self.dps_hwmon_exist and int(presence, 0):
+            self.dps_hwmon_exist = os.path.exists(self.dps_hwmon)
+            if not self.dps_hwmon_exist:
+                self._reload_dps_module()
+        return int(presence, 0)
+
+    def get_model(self):
+        """
+        Retrieves the part number of the PSU
+
+        Returns:
+            string: Part number of PSU
+        """
+        try: val = open(self.eeprom, "rb").read()[0x50:0x62]
+        except: val = None
+        return val.decode()
+
+    def get_serial(self):
+        """
+        Retrieves the serial number of the PSU
+
+        Returns:
+            string: Serial number of PSU
+        """
+        try: val = open(self.eeprom, "rb").read()[0xc4:0xd9]
+        except: val = None
+        return val.decode()
+
+    def get_status(self):
+        """
+        Retrieves the operational status of the PSU
+
+        Returns:
+            bool: True if PSU is operating properly, False if not
+        """
+        status = self._get_cpld_register(self.psu_status).strip()
+        if status == 'ERR' : return False
+        return int(status, 0)
+
+    def get_voltage(self):
+        """
+        Retrieves current PSU voltage output
+
+        Returns:
+            A float number, the output voltage in volts,
+            e.g. 12.1
+        """
+        voltage = 0.0
+        volt_reading = self._get_dps_register(self.psu_voltage_reg)
+        try:
+            voltage = int(volt_reading)/1000
+        except : return None
+        return "{:.1f}".format(voltage)
+
+    def get_current(self):
+        """
+        Retrieves present electric current supplied by PSU
+
+        Returns:
+            A float number, electric current in amperes,
+            e.g. 15.4
+        """
+        current = 0.0
+        curr_reading = self._get_dps_register(self.psu_current_reg)
+        try:
+            current = int(curr_reading)/1000
+        except : return None
+        return "{:.1f}".format(current)
+
+    def get_power(self):
+        """
+        Retrieves current energy supplied by PSU
+
+        Returns:
+            A float number, the power in watts,
+            e.g. 302.6
+        """
+        power = 0.0
+        power_reading = self._get_dps_register(self.psu_power_reg)
+        try:
+            power = int(power_reading)/1000
+        except : return None
+        return "{:.1f}".format(power)
+
+    def get_powergood_status(self):
+        """
+        Retrieves the powergood status of PSU
+
+        Returns:
+            A boolean, True if PSU has stablized its output voltages and
+            passed all its internal self-tests, False if not.
+        """
+        power_good  = self._get_cpld_register(self.psu_status).strip()
+        if power_good == 'ERR' : return False
+        return int(power_good, 0)
+
+    def get_mfr_id(self):
+        """
+        Retrives the Manufacturer Id of PSU
+
+        Returns:
+            A string, the manunfacturer id.
+        """
+        return 'DELTA'
+
+    def get_type(self):
+        """
+        Retrives the Power Type of PSU
+
+        Returns :
+            A string, PSU power type
+        """
+        try: val = open(self.eeprom, "rb").read()[0xe8:0xea]
+        except: return None
+        return val
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/sfp.py
new file mode 100644
index 000000000000..b071460985f3
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/sfp.py
@@ -0,0 +1,787 @@
+#!/usr/bin/env python
+
+#############################################################################
+# DELLEMC S5248F
+#
+# Module contains an implementation of SONiC Platform Base API and
+# provides the platform information
+#
+#############################################################################
+
+try:
+    import os
+    import time
+    import struct
+    import sys
+    import getopt
+    import select
+    import mmap
+    from sonic_platform_base.chassis_base import ChassisBase
+    from sonic_platform_base.sfp_base import SfpBase
+    from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId
+    from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom
+    from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId
+    from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom
+    from sonic_platform_base.sonic_sfp.sff8472 import sffbase
+
+except ImportError as e:
+    raise ImportError(str(e) + "- required module not found")
+
+PAGE_OFFSET = 0
+KEY_OFFSET = 1
+KEY_WIDTH = 2
+FUNC_NAME = 3
+
+QSFP_INFO_OFFSET = 128
+QSFP_DOM_OFFSET = 0
+QSFP_DOM_OFFSET1 = 384
+
+SFP_PORT_START = 49
+SFP_PORT_END = 54
+
+SFP_INFO_OFFSET = 0
+SFP_DOM_OFFSET = 256
+
+SFP_STATUS_CONTROL_OFFSET = 110
+SFP_STATUS_CONTROL_WIDTH = 7
+SFP_TX_DISABLE_HARD_BIT = 7
+SFP_TX_DISABLE_SOFT_BIT = 6
+
+qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', 'Length OM2(m)',
+                    'Length OM1(m)', 'Length Cable Assembly(m)')
+
+qsfp_compliance_code_tup = (
+    '10/40G Ethernet Compliance Code',
+    'SONET Compliance codes',
+    'SAS/SATA compliance codes',
+    'Gigabit Ethernet Compliant codes',
+    'Fibre Channel link length/Transmitter Technology',
+    'Fibre Channel transmission media',
+    'Fibre Channel Speed')
+
+sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)',
+                        'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)',
+                        'LengthOM3(UnitsOf10m)', 'LengthCable(UnitsOfm)')
+
+sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode',
+                           'ESCONComplianceCodes', 'SONETComplianceCodes',
+                           'EthernetComplianceCodes', 'FibreChannelLinkLength',
+                           'FibreChannelTechnology', 'SFP+CableTechnology',
+                           'FibreChannelTransmissionMedia', 'FibreChannelSpeed')
+
+info_dict_keys = ['type', 'hardware_rev', 'serial',
+                  'manufacturer', 'model', 'connector',
+                  'encoding', 'ext_identifier', 'ext_rateselect_compliance',
+                  'cable_type', 'cable_length', 'nominal_bit_rate',
+                  'specification_compliance', 'type_abbrv_name','vendor_date', 'vendor_oui']
+
+dom_dict_keys = ['rx_los',       'tx_fault',   'reset_status',
+                 'power_lpmode', 'tx_disable', 'tx_disable_channel',
+                 'temperature',  'voltage',    'rx1power',
+                 'rx2power',     'rx3power',   'rx4power',
+                 'tx1bias',      'tx2bias',    'tx3bias',
+                 'tx4bias',      'tx1power',   'tx2power',
+                 'tx3power',     'tx4power']
+
+threshold_dict_keys = ['temphighalarm',    'temphighwarning',
+                       'templowalarm',     'templowwarning',
+                       'vcchighalarm',     'vcchighwarning',
+                       'vcclowalarm',      'vcclowwarning',
+                       'rxpowerhighalarm', 'rxpowerhighwarning',
+                       'rxpowerlowalarm',  'rxpowerlowwarning',
+                       'txpowerhighalarm', 'txpowerhighwarning',
+                       'txpowerlowalarm',  'txpowerlowwarning',
+                       'txbiashighalarm',  'txbiashighwarning',
+                       'txbiaslowalarm',   'txbiaslowwarning']
+
+sff8436_parser = {
+     'reset_status': [QSFP_DOM_OFFSET,   2,  1, 'parse_dom_status_indicator'],
+           'rx_los': [QSFP_DOM_OFFSET,   3,  1, 'parse_dom_tx_rx_los'],
+         'tx_fault': [QSFP_DOM_OFFSET,   4,  1, 'parse_dom_tx_fault'],
+       'tx_disable': [QSFP_DOM_OFFSET,  86,  1, 'parse_dom_tx_disable'],
+     'power_lpmode': [QSFP_DOM_OFFSET,  93,  1, 'parse_dom_power_control'],
+   'power_override': [QSFP_DOM_OFFSET,  93,  1, 'parse_dom_power_control'],
+      'Temperature': [QSFP_DOM_OFFSET,  22,  2, 'parse_temperature'],
+          'Voltage': [QSFP_DOM_OFFSET,  26,  2, 'parse_voltage'],
+   'ChannelMonitor': [QSFP_DOM_OFFSET,  34, 16, 'parse_channel_monitor_params'],
+   'ChannelMonitor_TxPower':
+                     [QSFP_DOM_OFFSET,  34, 24, 'parse_channel_monitor_params_with_tx_power'],
+
+       'cable_type': [QSFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'],
+     'cable_length': [QSFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'],
+        'connector': [QSFP_INFO_OFFSET,  0, 20, 'parse_sfp_info_bulk'],
+             'type': [QSFP_INFO_OFFSET,  0, 20, 'parse_sfp_info_bulk'],
+         'encoding': [QSFP_INFO_OFFSET,  0, 20, 'parse_sfp_info_bulk'],
+   'ext_identifier': [QSFP_INFO_OFFSET,  0, 20, 'parse_sfp_info_bulk'],
+ 'ext_rateselect_compliance':
+                     [QSFP_INFO_OFFSET,  0, 20, 'parse_sfp_info_bulk'],
+ 'nominal_bit_rate': [QSFP_INFO_OFFSET,  0, 20, 'parse_sfp_info_bulk'],
+ 'specification_compliance':
+                     [QSFP_INFO_OFFSET,  0, 20, 'parse_sfp_info_bulk'],
+  'type_abbrv_name': [QSFP_INFO_OFFSET,  0, 20, 'parse_sfp_info_bulk'],
+     'manufacturer': [QSFP_INFO_OFFSET, 20, 16, 'parse_vendor_name'],
+       'vendor_oui': [QSFP_INFO_OFFSET, 37,  3, 'parse_vendor_oui'],
+            'model': [QSFP_INFO_OFFSET, 40, 16, 'parse_vendor_pn'],
+     'hardware_rev': [QSFP_INFO_OFFSET, 56,  2, 'parse_vendor_rev'],
+           'serial': [QSFP_INFO_OFFSET, 68, 16, 'parse_vendor_sn'],
+      'vendor_date': [QSFP_INFO_OFFSET, 84,  8, 'parse_vendor_date'],
+   'dom_capability': [QSFP_INFO_OFFSET, 92,  1, 'parse_qsfp_dom_capability'],
+          'dom_rev': [QSFP_DOM_OFFSET,   1,  1, 'parse_sfp_dom_rev'],
+  'ModuleThreshold': [QSFP_DOM_OFFSET1, 128, 24, 'parse_module_threshold_values'],
+ 'ChannelThreshold': [QSFP_DOM_OFFSET1, 176, 16, 'parse_channel_threshold_values'],
+}
+
+sff8472_parser = {
+      'Temperature': [SFP_DOM_OFFSET,  96,  2, 'parse_temperature'],
+          'Voltage': [SFP_DOM_OFFSET,  98,  2, 'parse_voltage'],
+   'ChannelMonitor': [SFP_DOM_OFFSET,  100, 6, 'parse_channel_monitor_params'],
+
+       'cable_type': [SFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'],
+     'cable_length': [SFP_INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'],
+        'connector': [SFP_INFO_OFFSET,  0, 21, 'parse_sfp_info_bulk'],
+             'type': [SFP_INFO_OFFSET,  0, 21, 'parse_sfp_info_bulk'],
+         'encoding': [SFP_INFO_OFFSET,  0, 21, 'parse_sfp_info_bulk'],
+   'ext_identifier': [SFP_INFO_OFFSET,  0, 21, 'parse_sfp_info_bulk'],
+ 'ext_rateselect_compliance':
+                     [SFP_INFO_OFFSET,  0, 21, 'parse_sfp_info_bulk'],
+ 'nominal_bit_rate': [SFP_INFO_OFFSET,  0, 21, 'parse_sfp_info_bulk'],
+ 'specification_compliance':
+                     [SFP_INFO_OFFSET,  0, 21, 'parse_sfp_info_bulk'],
+  'type_abbrv_name': [SFP_INFO_OFFSET,  0, 21, 'parse_sfp_info_bulk'],
+     'manufacturer': [SFP_INFO_OFFSET, 20, 16, 'parse_vendor_name'],
+       'vendor_oui': [SFP_INFO_OFFSET,  37, 3, 'parse_vendor_oui'],
+            'model': [SFP_INFO_OFFSET, 40, 16, 'parse_vendor_pn'],
+     'hardware_rev': [SFP_INFO_OFFSET, 56,  4, 'parse_vendor_rev'],
+           'serial': [SFP_INFO_OFFSET, 68, 16, 'parse_vendor_sn'],
+      'vendor_date': [SFP_INFO_OFFSET, 84,  8, 'parse_vendor_date'],
+  'ModuleThreshold': [SFP_DOM_OFFSET,   0, 56, 'parse_alarm_warning_threshold'],
+}
+
+
+class Sfp(SfpBase):
+    """
+    DELLEMC Platform-specific Sfp class
+    """
+
+    def __init__(self, index, sfp_type, eeprom_path):
+        SfpBase.__init__(self)
+        self.sfp_type = sfp_type
+        self.index = index
+        self.eeprom_path = eeprom_path
+        self.qsfpInfo = sff8436InterfaceId()
+        self.qsfpDomInfo = sff8436Dom()
+        self.sfpInfo = sff8472InterfaceId()
+        self.sfpDomInfo = sff8472Dom(None,1)
+
+    def get_eeprom_sysfs_path(self):
+        return self.eeprom_path
+
+    def pci_mem_read(self, mm, offset):
+        mm.seek(offset)
+        read_data_stream = mm.read(4)
+        reg_val = struct.unpack('I', read_data_stream)
+        mem_val = str(reg_val)[1:-2]
+        # print "reg_val read:%x"%reg_val
+        return mem_val
+
+    def pci_mem_write(self, mm, offset, data):
+        mm.seek(offset)
+        # print "data to write:%x"%data
+        mm.write(struct.pack('I', data))
+
+    def pci_set_value(self, resource, val, offset):
+        fd = os.open(resource, os.O_RDWR)
+        mm = mmap.mmap(fd, 0)
+        val = self.pci_mem_write(mm, offset, val)
+        mm.close()
+        os.close(fd)
+        return val
+
+    def pci_get_value(self, resource, offset):
+        fd = os.open(resource, os.O_RDWR)
+        mm = mmap.mmap(fd, 0)
+        val = self.pci_mem_read(mm, offset)
+        mm.close()
+        os.close(fd)
+        return val
+
+    def _read_eeprom_bytes(self, eeprom_path, offset, num_bytes):
+        eeprom_raw = []
+        try:
+            eeprom = open(eeprom_path, mode="rb", buffering=0)
+        except IOError:
+            return None
+
+        for i in range(0, num_bytes):
+            eeprom_raw.append("0x00")
+
+        try:
+            eeprom.seek(offset)
+            raw = eeprom.read(num_bytes)
+        except IOError:
+            eeprom.close()
+            return None
+
+        raw = bytearray(raw)
+
+        try:
+            for n in range(0, num_bytes):
+                eeprom_raw[n] = hex((raw[n]))[2:].zfill(2)
+        except BaseException:
+            eeprom.close()
+            return None
+
+        eeprom.close()
+        return eeprom_raw
+
+    def _get_eeprom_data(self, eeprom_key):
+        eeprom_data = None
+        page_offset = None
+
+        if(self.sfp_type == 'QSFP'):
+            page_offset = sff8436_parser[eeprom_key][PAGE_OFFSET]
+            eeprom_data_raw = self._read_eeprom_bytes(
+                self.eeprom_path,
+                (sff8436_parser[eeprom_key][PAGE_OFFSET] +
+                 sff8436_parser[eeprom_key][KEY_OFFSET]),
+                 sff8436_parser[eeprom_key][KEY_WIDTH])
+            if (eeprom_data_raw is not None):
+                # Offset 128 is used to retrieve sff8436InterfaceId Info
+                # Offset 0 is used to retrieve sff8436Dom Info
+                if (page_offset == 128):
+                    if ( self.qsfpInfo is None):
+                        return None
+                    eeprom_data = getattr(
+                        self.qsfpInfo, sff8436_parser[eeprom_key][FUNC_NAME])(
+                        eeprom_data_raw, 0)
+                else:
+                    if ( self.qsfpDomInfo is None):
+                        return None
+                    eeprom_data = getattr(
+                        self.qsfpDomInfo, sff8436_parser[eeprom_key][FUNC_NAME])(
+                        eeprom_data_raw, 0)
+        else:
+            page_offset = sff8472_parser[eeprom_key][PAGE_OFFSET]
+            eeprom_data_raw = self._read_eeprom_bytes(
+                self.eeprom_path,
+                (sff8472_parser[eeprom_key][PAGE_OFFSET] +
+                 sff8472_parser[eeprom_key][KEY_OFFSET]),
+                 sff8472_parser[eeprom_key][KEY_WIDTH])
+            if (eeprom_data_raw is not None):
+                # Offset 0 is used to retrieve sff8472InterfaceId Info
+                # Offset 256 is used to retrieve sff8472Dom Info
+                if (page_offset == 0):
+                    if ( self.sfpInfo is None):
+                        return None
+                    eeprom_data = getattr(
+                        self.sfpInfo, sff8472_parser[eeprom_key][FUNC_NAME])(
+                        eeprom_data_raw, 0)
+                else:
+                    if ( self.sfpDomInfo is None):
+                        return None
+                    eeprom_data = getattr(
+                        self.sfpDomInfo, sff8472_parser[eeprom_key][FUNC_NAME])(
+                        eeprom_data_raw, 0)
+
+        return eeprom_data
+
+    def get_transceiver_info(self):
+        """
+        Retrieves transceiver info of this SFP
+        """
+        transceiver_info_dict = {}
+        compliance_code_dict = {}
+        transceiver_info_dict = dict.fromkeys(info_dict_keys, 'N/A')
+        # BaseInformation
+        try:
+            iface_data = self._get_eeprom_data('type')
+            connector = iface_data['data']['Connector']['value']
+            encoding = iface_data['data']['EncodingCodes']['value']
+            ext_id = iface_data['data']['Extended Identifier']['value']
+            rate_identifier = iface_data['data']['RateIdentifier']['value']
+            identifier = iface_data['data']['type']['value']
+            type_abbrv_name=iface_data['data']['type_abbrv_name']['value']
+            if(self.sfp_type == 'QSFP'):
+                bit_rate = str(
+                    iface_data['data']['Nominal Bit Rate(100Mbs)']['value'])
+                for key in qsfp_compliance_code_tup:
+                    if key in iface_data['data']['Specification compliance']['value']:
+                        compliance_code_dict[key] = iface_data['data']['Specification compliance']['value'][key]['value']
+                for key in qsfp_cable_length_tup:
+                    if key in iface_data['data']:
+                        cable_type = key
+                        cable_length = str(iface_data['data'][key]['value'])
+            else:
+                bit_rate = str(
+                    iface_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value'])
+                for key in sfp_compliance_code_tup:
+                    if key in iface_data['data']['Specification compliance']['value']:
+                        compliance_code_dict[key] = iface_data['data']['Specification compliance']['value'][key]['value']
+                for key in sfp_cable_length_tup:
+                    if key in iface_data['data']:
+                        cable_type = key
+                        cable_length = str(iface_data['data'][key]['value'])
+
+            transceiver_info_dict['type_abbrv_name']=type_abbrv_name
+            transceiver_info_dict['type'] = identifier
+            transceiver_info_dict['connector'] = connector
+            transceiver_info_dict['encoding'] = encoding
+            transceiver_info_dict['ext_identifier'] = ext_id
+            transceiver_info_dict['ext_rateselect_compliance'] = rate_identifier
+            transceiver_info_dict['cable_type'] = cable_type
+            transceiver_info_dict['cable_length'] = cable_length
+            transceiver_info_dict['nominal_bit_rate'] = bit_rate
+            transceiver_info_dict['specification_compliance'] = str(compliance_code_dict)
+        except (ValueError, TypeError) : pass
+
+        # Vendor Date
+        try:
+            vendor_date_data = self._get_eeprom_data('vendor_date')
+            vendor_date = vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value']
+            transceiver_info_dict['vendor_date'] = vendor_date
+        except (ValueError, TypeError) : pass
+
+        # Vendor Name
+        try:
+            vendor_name_data = self._get_eeprom_data('manufacturer')
+            vendor_name = vendor_name_data['data']['Vendor Name']['value']
+            transceiver_info_dict['manufacturer'] = vendor_name
+        except (ValueError, TypeError) : pass
+
+        # Vendor OUI
+        try:
+            vendor_oui_data = self._get_eeprom_data('vendor_oui')
+            vendor_oui = vendor_oui_data['data']['Vendor OUI']['value']
+            transceiver_info_dict['vendor_oui'] = vendor_oui
+        except (ValueError, TypeError) : pass
+
+        # Vendor PN
+        try:
+            vendor_pn_data = self._get_eeprom_data('model')
+            vendor_pn = vendor_pn_data['data']['Vendor PN']['value']
+            transceiver_info_dict['model'] = vendor_pn
+        except (ValueError, TypeError) : pass
+
+        # Vendor Revision
+        try:
+            vendor_rev_data = self._get_eeprom_data('hardware_rev')
+            vendor_rev = vendor_rev_data['data']['Vendor Rev']['value']
+            transceiver_info_dict['hardware_rev'] = vendor_rev
+        except (ValueError, TypeError) : pass
+
+        # Vendor Serial Number
+        try:
+            vendor_sn_data = self._get_eeprom_data('serial')
+            vendor_sn = vendor_sn_data['data']['Vendor SN']['value']
+            transceiver_info_dict['serial'] = vendor_sn
+        except (ValueError, TypeError) : pass
+
+        return transceiver_info_dict
+
+    def get_transceiver_threshold_info(self):
+        """
+        Retrieves transceiver threshold info of this SFP
+        """
+        transceiver_dom_threshold_dict = {}
+        transceiver_dom_threshold_dict = dict.fromkeys(
+                threshold_dict_keys, 'N/A')
+
+        try:
+            # Module Threshold
+            module_threshold_data = self._get_eeprom_data('ModuleThreshold')
+            if (self.sfp_type == 'QSFP'):
+                transceiver_dom_threshold_dict['temphighalarm'] = module_threshold_data['data']['TempHighAlarm']['value']
+                transceiver_dom_threshold_dict['temphighwarning'] = module_threshold_data['data']['TempHighWarning']['value']
+                transceiver_dom_threshold_dict['templowalarm'] = module_threshold_data['data']['TempLowAlarm']['value']
+                transceiver_dom_threshold_dict['templowwarning'] = module_threshold_data['data']['TempLowWarning']['value']
+                transceiver_dom_threshold_dict['vcchighalarm'] = module_threshold_data['data']['VccHighAlarm']['value']
+                transceiver_dom_threshold_dict['vcchighwarning'] = module_threshold_data['data']['VccHighWarning']['value']
+                transceiver_dom_threshold_dict['vcclowalarm'] = module_threshold_data['data']['VccLowAlarm']['value']
+                transceiver_dom_threshold_dict['vcclowwarning'] = module_threshold_data['data']['VccLowWarning']['value']
+            else:  #SFP
+                transceiver_dom_threshold_dict['temphighalarm'] = module_threshold_data['data']['TempHighAlarm']['value']
+                transceiver_dom_threshold_dict['templowalarm'] = module_threshold_data['data']['TempLowAlarm']['value']
+                transceiver_dom_threshold_dict['temphighwarning'] = module_threshold_data['data']['TempHighWarning']['value']
+                transceiver_dom_threshold_dict['templowwarning'] = module_threshold_data['data']['TempLowWarning']['value']
+                transceiver_dom_threshold_dict['vcchighalarm'] = module_threshold_data['data']['VoltageHighAlarm']['value']
+                transceiver_dom_threshold_dict['vcclowalarm'] = module_threshold_data['data']['VoltageLowAlarm']['value']
+                transceiver_dom_threshold_dict['vcchighwarning'] = module_threshold_data['data']['VoltageHighWarning']['value']
+                transceiver_dom_threshold_dict['vcclowwarning'] = module_threshold_data['data']['VoltageLowWarning']['value']
+                transceiver_dom_threshold_dict['txbiashighalarm'] = module_threshold_data['data']['BiasHighAlarm']['value']
+                transceiver_dom_threshold_dict['txbiaslowalarm'] = module_threshold_data['data']['BiasLowAlarm']['value']
+                transceiver_dom_threshold_dict['txbiashighwarning'] = module_threshold_data['data']['BiasHighWarning']['value']
+                transceiver_dom_threshold_dict['txbiaslowwarning'] = module_threshold_data['data']['BiasLowWarning']['value']
+                transceiver_dom_threshold_dict['txpowerhighalarm'] = module_threshold_data['data']['TXPowerHighAlarm']['value']
+                transceiver_dom_threshold_dict['txpowerlowalarm'] = module_threshold_data['data']['TXPowerLowAlarm']['value']
+                transceiver_dom_threshold_dict['txpowerhighwarning'] = module_threshold_data['data']['TXPowerHighWarning']['value']
+                transceiver_dom_threshold_dict['txpowerlowwarning'] = module_threshold_data['data']['TXPowerLowWarning']['value']
+                transceiver_dom_threshold_dict['rxpowerhighalarm'] = module_threshold_data['data']['RXPowerHighAlarm']['value']
+                transceiver_dom_threshold_dict['rxpowerlowalarm'] = module_threshold_data['data']['RXPowerLowAlarm']['value']
+                transceiver_dom_threshold_dict['rxpowerhighwarning'] = module_threshold_data['data']['RXPowerHighWarning']['value']
+                transceiver_dom_threshold_dict['rxpowerlowwarning'] = module_threshold_data['data']['RXPowerLowWarning']['value']
+        except (ValueError, TypeError) : pass
+
+        try:
+            if (self.sfp_type == 'QSFP'):
+                channel_threshold_data = self._get_eeprom_data('ChannelThreshold')
+                transceiver_dom_threshold_dict['rxpowerhighalarm'] = channel_threshold_data['data']['RxPowerHighAlarm']['value']
+                transceiver_dom_threshold_dict['rxpowerhighwarning'] = channel_threshold_data['data']['RxPowerHighWarning']['value']
+                transceiver_dom_threshold_dict['rxpowerlowalarm'] = channel_threshold_data['data']['RxPowerLowAlarm']['value']
+                transceiver_dom_threshold_dict['rxpowerlowwarning'] = channel_threshold_data['data']['RxPowerLowWarning']['value']
+                transceiver_dom_threshold_dict['txbiashighalarm'] = channel_threshold_data['data']['TxBiasHighAlarm']['value']
+                transceiver_dom_threshold_dict['txbiashighwarning'] = channel_threshold_data['data']['TxBiasHighWarning']['value']
+                transceiver_dom_threshold_dict['txbiaslowalarm'] = channel_threshold_data['data']['TxBiasLowAlarm']['value']
+                transceiver_dom_threshold_dict['txbiaslowwarning'] = channel_threshold_data['data']['TxBiasLowWarning']['value']
+
+        except (ValueError, TypeError) : pass
+        return transceiver_dom_threshold_dict
+
+    def get_transceiver_bulk_status(self):
+        """
+        Retrieves transceiver bulk status of this SFP
+        """
+        tx_bias_list = []
+        rx_power_list = []
+        transceiver_dom_dict = {}
+        transceiver_dom_dict = dict.fromkeys(dom_dict_keys, 'N/A')
+
+        # RxLos
+        rx_los = self.get_rx_los()
+
+        # TxFault
+        tx_fault = self.get_tx_fault()
+
+        # ResetStatus
+        reset_state = self.get_reset_status()
+
+        # LowPower Mode
+        lp_mode = self.get_lpmode()
+
+        # TxDisable
+        tx_disable = self.get_tx_disable()
+
+        # TxDisable Channel
+        tx_disable_channel = self.get_tx_disable_channel()
+
+        # Temperature
+        temperature = self.get_temperature()
+
+        # Voltage
+        voltage = self.get_voltage()
+
+        # Channel Monitor
+        tx_power_list = self.get_tx_power()
+
+        # tx bias
+        tx_bias_list = self.get_tx_bias()
+
+        # rx power
+        rx_power_list = self.get_rx_power()
+
+        if tx_bias_list is not None:
+            transceiver_dom_dict['tx1bias'] = tx_bias_list[0]
+            transceiver_dom_dict['tx2bias'] = tx_bias_list[1]
+            transceiver_dom_dict['tx3bias'] = tx_bias_list[2]
+            transceiver_dom_dict['tx4bias'] = tx_bias_list[3]
+
+        if rx_power_list is not None:
+            transceiver_dom_dict['rx1power'] = rx_power_list[0]
+            transceiver_dom_dict['rx2power'] = rx_power_list[1]
+            transceiver_dom_dict['rx3power'] = rx_power_list[2]
+            transceiver_dom_dict['rx4power'] = rx_power_list[3]
+
+        if tx_power_list is not None:
+            transceiver_dom_dict['tx1power'] = tx_power_list[0]
+            transceiver_dom_dict['tx2power'] = tx_power_list[1]
+            transceiver_dom_dict['tx3power'] = tx_power_list[2]
+            transceiver_dom_dict['tx4power'] = tx_power_list[3]
+
+        transceiver_dom_dict['rx_los'] = rx_los
+        transceiver_dom_dict['tx_fault'] = tx_fault
+        transceiver_dom_dict['reset_status'] = reset_state
+        transceiver_dom_dict['power_lpmode'] = lp_mode
+        transceiver_dom_dict['tx_disable'] = tx_disable
+        transceiver_dom_dict['tx_disable_channel'] = tx_disable_channel
+        transceiver_dom_dict['temperature'] = temperature
+        transceiver_dom_dict['voltage'] = voltage
+
+        return transceiver_dom_dict
+
+    def get_name(self):
+        """
+        Retrieves the name of the sfp
+        Returns : QSFP or QSFP+ or QSFP28
+        """
+        try:
+            iface_data = self._get_eeprom_data('type')
+            identifier = iface_data['data']['type']['value']
+        except (TypeError, ValueError):
+            return 'N/A'
+        return identifier
+
+    def _get_cpld_register(self, reg):
+        reg_file = '/sys/devices/platform/dell-n3248te-cpld.0/' + reg
+        try:
+            rv = open(reg_file, 'r').read()
+        except IOError : return 'ERR'
+        return rv.strip('\r\n').lstrip(' ')
+
+    def get_presence(self):
+        """
+        Retrieves the presence of the sfp
+        Returns : True if sfp is present and false if it is absent
+        """
+        # Check for invalid port_num
+        presence = False
+        if not (self.index >= SFP_PORT_START and self.index <= SFP_PORT_END): return presence
+        bit_mask = 1 << (self.index - SFP_PORT_START)
+        try:
+            sfp_mod_prs = self._get_cpld_register('sfp_modprs')
+            if sfp_mod_prs == 'ERR' : return presence
+            presence =  ((int(sfp_mod_prs, 16) & bit_mask) == 0)
+        except: pass
+        return presence
+
+    def get_model(self):
+        """
+        Retrieves the model number (or part number) of the sfp
+        """
+        try:
+            vendor_pn_data = self._get_eeprom_data('model')
+            vendor_pn = vendor_pn_data['data']['Vendor PN']['value']
+        except (TypeError, ValueError):
+            return 'N/A'
+
+        return vendor_pn
+
+    def get_serial(self):
+        """
+        Retrieves the serial number of the sfp
+        """
+        try:
+            vendor_sn_data = self._get_eeprom_data('serial')
+            vendor_sn = vendor_sn_data['data']['Vendor SN']['value']
+        except (TypeError, ValueError):
+            return 'N/A'
+
+        return vendor_sn
+
+    def get_reset_status(self):
+        """
+        Retrives the reset status of SFP
+        """
+        reset_status = False
+        return reset_status
+
+    def get_rx_los(self):
+        """
+        Retrieves the RX LOS (lost-of-signal) status of SFP
+        """
+        rx_los = False
+        if not (self.index >= SFP_PORT_START and self.index <= SFP_PORT_END): return rx_los
+        bit_mask = 1 << (self.index - SFP_PORT_START)
+        try:
+            sfp_rxlos = self._get_cpld_register('sfp_rxlos')
+            if sfp_rxlos == 'ERR' : return rx_los
+            rx_los =  ((int(sfp_rxlos, 16) & bit_mask) != 0)
+        except: pass
+        return rx_los
+
+    def get_tx_fault(self):
+        """
+        Retrieves the TX fault status of SFP
+        """
+        tx_fault = False
+        if not (self.index >= SFP_PORT_START and self.index <= SFP_PORT_END): return tx_fault
+        bit_mask = 1 << (self.index - SFP_PORT_START)
+        try:
+            sfp_txfault = self._get_cpld_register('sfp_txfault')
+            if sfp_txfault == 'ERR' : return tx_fault
+            tx_fault =  ((int(sfp_txfault, 16) & bit_mask) != 0)
+        except: pass
+        return tx_fault
+
+    def get_tx_disable(self):
+        """
+        Retrieves the tx_disable status of this SFP
+        """
+        tx_disable = False
+        if not (self.index >= SFP_PORT_START and self.index <= SFP_PORT_END): return tx_disable
+        bit_mask = 1 << (self.index - SFP_PORT_START)
+        try:
+            sfp_txdisable = self._get_cpld_register('sfp_txdis')
+            if sfp_txdisable == 'ERR' : return tx_disable
+            tx_disable =  ((int(sfp_txdisable, 16) & bit_mask) != 0)
+        except: pass
+        return tx_disable
+
+    def get_tx_disable_channel(self):
+        """
+        Retrieves the TX disabled channels in this SFP
+        """
+        tx_disable_channel = 0
+        try:
+            if (self.sfp_type == 'QSFP'):
+                tx_disable_data = self._get_eeprom_data('tx_disable')
+                for tx_disable_id in ('Tx1Disable', 'Tx2Disable', 'Tx3Disable', 'Tx4Disable'):
+                    tx_disable_channel <<= 1
+                    tx_disable_channel |= (tx_disable_data['data']['Tx1Disable']['value'] is 'On')
+        except (TypeError, ValueError):
+            return 'N/A'
+        return tx_disable_channel
+
+    def get_lpmode(self):
+        """
+        Retrieves the lpmode(low power mode) of this SFP
+        """
+        lpmode_state = False
+        return lpmode_state
+
+    def get_power_override(self):
+        """
+        Retrieves the power-override status of this SFP
+        """
+        power_override_state = False
+
+        try:
+            if (self.sfp_type == 'QSFP'):
+                power_override_data = self._get_eeprom_data('power_override')
+                power_override = power_override_data['data']['PowerOverRide']['value']
+                power_override_state = (power_override is 'On')
+        except (TypeError, ValueError): pass
+        return power_override_state
+
+    def get_temperature(self):
+        """
+        Retrieves the temperature of this SFP
+        """
+        temperature = 'N/A'
+        try :
+            temperature_data = self._get_eeprom_data('Temperature')
+            temperature = temperature_data['data']['Temperature']['value']
+        except (TypeError, ValueError):
+            return 'N/A'
+        return temperature
+
+    def get_voltage(self):
+        """
+        Retrieves the supply voltage of this SFP
+        """
+        voltage = 'N/A'
+        try:
+            voltage_data = self._get_eeprom_data('Voltage')
+            voltage = voltage_data['data']['Vcc']['value']
+        except (TypeError, ValueError):
+            return 'N/A'
+        return voltage
+
+    def get_tx_bias(self):
+        """
+        Retrieves the TX bias current of this SFP
+        """
+        tx_bias_list = []
+        try:
+            tx_bias_data = self._get_eeprom_data('ChannelMonitor')
+            if (self.sfp_type == 'QSFP'):
+                for tx_bias_id in ('TX1Bias', 'TX2Bias', 'TX3Bias', 'TX4Bias') :
+                    tx_bias = tx_bias_data['data'][tx_bias_id]['value']
+                    tx_bias_list.append(tx_bias)
+            else:
+                tx1_bias = tx_bias_data['data']['TXBias']['value']
+                tx_bias_list =  [tx1_bias, "N/A", "N/A", "N/A"]
+        except (TypeError, ValueError):
+            return None
+        return tx_bias_list
+
+    def get_rx_power(self):
+        """
+        Retrieves the received optical power for this SFP
+        """
+        rx_power_list = []
+        try:
+            rx_power_data = self._get_eeprom_data('ChannelMonitor')
+            if (self.sfp_type == 'QSFP'):
+                for rx_power_id in ('RX1Power', 'RX2Power', 'RX3Power', 'RX4Power'):
+                    rx_power = rx_power_data['data'][rx_power_id]['value']
+                    rx_power_list.append(rx_power)
+            else:
+                rx1_pw = rx_power_data['data']['RXPower']['value']
+                rx_power_list =  [rx1_pw, "N/A", "N/A", "N/A"]
+        except (TypeError, ValueError):
+            return None
+        return rx_power_list
+
+    def get_tx_power(self):
+        """
+        Retrieves the TX power of this SFP
+        """
+        tx_power_list = []
+        try:
+            if(self.sfp_type == 'QSFP'):
+                # QSFP capability byte parse, through this byte can know whether it support tx_power or not.
+                # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436,
+                # need to add more code for determining the capability and version compliance
+                # in SFF-8636 dom capability definitions evolving with the versions.
+                qspf_dom_capability_data = self._get_eeprom_data('dom_capability')
+                qsfp_dom_rev_data = self._get_eeprom_data('dom_rev')
+                qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value']
+                qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value']
+
+                # The tx_power monitoring is only available on QSFP which compliant with SFF-8636
+                # and claimed that it support tx_power with one indicator bit.
+                if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')):
+                    return None
+                channel_monitor_data = self._get_eeprom_data('ChannelMonitor_TxPower')
+                for tx_power_id in ('TX1Power', 'TX2Power', 'TX3Power', 'TX4Power'):
+                    tx_pw = channel_monitor_data['data'][tx_power_id]['value']
+                    tx_power_list.append(tx_pw)
+            else:
+                channel_monitor_data = self._get_eeprom_data('ChannelMonitor')
+                tx1_pw = channel_monitor_data['data']['TXPower']['value']
+                tx_power_list = [tx1_pw, 'N/A', 'N/A', 'N/A']
+        except (TypeError, ValueError):
+            return None
+        return tx_power_list
+
+    def reset(self):
+        """
+        Reset the SFP and returns all user settings to their default state
+        """
+        return True
+
+    def set_lpmode(self, lpmode):
+        """
+        Sets the lpmode(low power mode) of this SFP
+        """
+        return True
+
+    def tx_disable(self, tx_disable):
+        """
+        Disable SFP TX for all channels
+        """
+        return False
+
+    def tx_disable_channel(self, channel, disable):
+        """
+        Sets the tx_disable for specified SFP channels
+        """
+        return False
+
+    def set_power_override(self, power_override, power_set):
+        """
+        Sets SFP power level using power_override and power_set
+        """
+        return False
+
+    def get_status(self):
+        """
+        Retrieves the operational status of the device
+        """
+        reset = self.get_reset_status()
+        return (not reset)
+
+    def get_max_port_power(self):
+        """
+        Retrieves the maximumum power allowed on the port in watts
+        """
+        return 2.5
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/thermal.py
new file mode 100644
index 000000000000..cdbd74562392
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/thermal.py
@@ -0,0 +1,145 @@
+#!/usr/bin/env python
+
+########################################################################
+# DellEMC Z9332F
+#
+# Module contains an implementation of SONiC Platform Base API and
+# provides the Thermals' information which are available in the platform
+#
+########################################################################
+
+
+try:
+    import os
+    from sonic_platform_base.thermal_base import ThermalBase
+except ImportError as e:
+    raise ImportError(str(e) + "- required module not found")
+
+
+class Thermal(ThermalBase):
+    """DellEMC Platform-specific Thermal class"""
+
+    # [ Sensor-Name, Sensor-ID ]
+    SENSOR_MAPPING = [
+        ['Switch Near Temperature', '7-0049'],
+        ['Switch Rear Temperature', '7-004a'],
+        ['Front Panel PHY Temperature', '7-004b'],
+        ['Near Front Panel Temperature', '7-004c'],
+        ['Middle Fan Tray Temperature', '7-004f'],
+    ]
+
+    def __init__(self, thermal_index):
+        ThermalBase.__init__(self)
+        self.index = thermal_index + 1
+        temp_hwmon = '/sys/bus/i2c/devices/' + self.SENSOR_MAPPING[thermal_index][1] + '/hwmon'
+        self.temp_file = temp_hwmon + '/' + os.listdir(temp_hwmon)[0] + '/' + 'temp1_input'
+
+    def get_name(self):
+        """
+        Retrieves the name of the thermal
+
+        Returns:
+            string: The name of the thermal
+        """
+        return self.SENSOR_MAPPING[self.index - 1][0]
+
+    def get_presence(self):
+        """
+        Retrieves the presence of the thermal
+
+        Returns:
+            bool: True if thermal is present, False if not
+        """
+        return True
+
+    def get_model(self):
+        """
+        Retrieves the model number (or part number) of the Thermal
+
+        Returns:
+            string: Model/part number of Thermal
+        """
+        return 'NA'
+
+    def get_serial(self):
+        """
+        Retrieves the serial number of the Thermal
+
+        Returns:
+            string: Serial number of Thermal
+        """
+        return 'NA'
+
+    def get_status(self):
+        """
+        Retrieves the operational status of the thermal
+
+        Returns:
+            A boolean value, True if thermal is operating properly,
+            False if not
+        """
+        return True
+
+    def get_temperature(self):
+        """
+        Retrieves current temperature reading from thermal
+
+        Returns:
+            A float number of current temperature in Celsius up to
+            nearest thousandth of one degree Celsius, e.g. 30.125
+        """
+        temperature = 0.0
+        try :
+            temperature = float(open(self.temp_file).read()) / 1000.0
+        except : pass
+        return float(temperature)
+
+    def get_high_threshold(self):
+        """
+        Retrieves the high threshold temperature of thermal
+
+        Returns:
+            A float number, the high threshold temperature of thermal in
+            Celsius up to nearest thousandth of one degree Celsius,
+            e.g. 30.125
+        """
+        return 75.0
+
+    def get_low_threshold(self):
+        """
+        Retrieves the low threshold temperature of thermal
+
+        Returns:
+            A float number, the low threshold temperature of thermal in
+            Celsius up to nearest thousandth of one degree Celsius,
+            e.g. 30.125
+        """
+        return 0.0
+
+    def set_high_threshold(self, temperature):
+        """
+        Sets the high threshold temperature of thermal
+
+        Args :
+            temperature: A float number up to nearest thousandth of one
+            degree Celsius, e.g. 30.125
+        Returns:
+            A boolean, True if threshold is set successfully, False if
+            not
+        """
+        # Thermal threshold values are pre-defined based on HW.
+        return False
+
+    def set_low_threshold(self, temperature):
+        """
+        Sets the low threshold temperature of thermal
+
+        Args :
+            temperature: A float number up to nearest thousandth of one
+            degree Celsius, e.g. 30.125
+        Returns:
+            A boolean, True if threshold is set successfully, False if
+            not
+        """
+        # Thermal threshold values are pre-defined based on HW.
+        return False
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/watchdog.py
new file mode 100644
index 000000000000..90a6c7f6eef4
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/watchdog.py
@@ -0,0 +1,214 @@
+#!/usr/bin/env python
+
+########################################################################
+#
+# DELLEMC Z9332F
+#
+# Abstract base class for implementing a platform-specific class with
+# which to interact with a hardware watchdog module in SONiC
+#
+########################################################################
+
+try:
+    import sys
+    import struct
+    import ctypes
+    import subprocess
+    from sonic_platform_base.watchdog_base import WatchdogBase
+except ImportError as e:
+    raise ImportError(str(e) + "- required module not found")
+
+
+class _timespec(ctypes.Structure):
+    _fields_ = [
+            ('tv_sec', ctypes.c_long),
+            ('tv_nsec', ctypes.c_long)
+    ]
+
+
+class Watchdog(WatchdogBase):
+    """
+    Abstract base class for interfacing with a hardware watchdog module
+    """
+
+    TIMERS = [15,20,30,40,50,60,65,70]
+
+    armed_time = 0
+    timeout = 0
+    CLOCK_MONOTONIC = 1
+
+    def __init__(self):
+        self._librt = ctypes.CDLL('librt.so.1', use_errno=True)
+        self._clock_gettime = self._librt.clock_gettime
+        self._clock_gettime.argtypes=[ctypes.c_int, ctypes.POINTER(_timespec)]
+
+    def _get_command_result(self, cmdline):
+        try:
+            proc = subprocess.Popen(cmdline.split(), stdout=subprocess.PIPE,
+                    stderr=subprocess.STDOUT)
+            stdout = proc.communicate()[0]
+            proc.wait()
+            result = stdout.rstrip('\n')
+        except OSError:
+            result = None
+
+        return result
+
+    def _get_reg_val(self):
+        # 0x31 = CPLD I2C Base Address
+        # 0x07 = Watchdog Function Register
+        value = self._get_command_result("/usr/sbin/i2cget -y 601 0x31 0x07")
+        if not value:
+            return None
+        else:
+            return int(value, 16)
+
+    def _set_reg_val(self,val):
+        # 0x31 = CPLD I2C Base Address
+        # 0x07 = Watchdog Function Register
+        value = self._get_command_result("/usr/sbin/i2cset -y 601 0x31 0x07 %s"
+                % (val))
+        return value
+
+    def _get_time(self):
+        """
+        To get clock monotonic time
+        """
+        ts = _timespec()
+        if self._clock_gettime(self.CLOCK_MONOTONIC, ctypes.pointer(ts)) != 0:
+            self._errno = ctypes.get_errno()
+            return 0
+        return ts.tv_sec + ts.tv_nsec * 1e-9
+
+    def arm(self, seconds):
+        """
+        Arm the hardware watchdog with a timeout of <seconds> seconds.
+        If the watchdog is currently armed, calling this function will
+        simply reset the timer to the provided value. If the underlying
+        hardware does not support the value provided in <seconds>, this
+        method should arm the watchdog with the *next greater*
+        available value.
+
+        Returns:
+            An integer specifying the *actual* number of seconds the
+            watchdog was armed with. On failure returns -1.
+        """
+        timer_offset = -1
+        for key,timer_seconds in enumerate(self.TIMERS):
+            if seconds <= timer_seconds:
+                timer_offset = key
+                seconds = timer_seconds
+                break
+
+        if timer_offset == -1:
+            return -1
+
+        # Extracting 5th to 7th bits for WD timer values
+        # 000 - 15 sec
+        # 001 - 20 sec
+        # 010 - 30 sec
+        # 011 - 40 sec
+        # 100 - 50 sec
+        # 101 - 60 sec
+        # 110 - 65 sec
+        # 111 - 70 sec
+        reg_val = self._get_reg_val()
+        wd_timer_offset = (reg_val >> 4) & 0x7
+
+        if wd_timer_offset != timer_offset:
+            # Setting 5th to 7th bits
+            # value from timer_offset
+            self.disarm()
+            self._set_reg_val(reg_val | (timer_offset << 4))
+
+        if self.is_armed():
+            # Setting last bit to WD Timer punch
+            # Last bit = WD Timer punch
+            self._set_reg_val(reg_val & 0xFE)
+
+            self.armed_time = self._get_time()
+            self.timeout = seconds
+            return seconds
+        else:
+            # Setting 4th bit to enable WD
+            # 4th bit = Enable WD
+            reg_val = self._get_reg_val()
+            self._set_reg_val(reg_val | 0x8)
+
+            self.armed_time = self._get_time()
+            self.timeout = seconds
+            return seconds
+
+        return -1
+
+    def disarm(self):
+        """
+        Disarm the hardware watchdog
+
+        Returns:
+            A boolean, True if watchdog is disarmed successfully, False
+            if not
+        """
+        if self.is_armed():
+            # Setting 4th bit to disable WD
+            # 4th bit = Disable WD
+            reg_val = self._get_reg_val()
+            self._set_reg_val(reg_val & 0xF7)
+
+            self.armed_time = 0
+            self.timeout = 0
+            return True
+
+        return False
+
+    def is_armed(self):
+        """
+        Retrieves the armed state of the hardware watchdog.
+
+        Returns:
+            A boolean, True if watchdog is armed, False if not
+        """
+
+        # Extracting 4th bit to get WD Enable/Disable status
+        # 0 - Disabled WD
+        # 1 - Enabled WD
+        reg_val = self._get_reg_val()
+        wd_offset = (reg_val >> 3) & 1
+
+        return bool(wd_offset)
+
+    def get_remaining_time(self):
+        """
+        If the watchdog is armed, retrieve the number of seconds
+        remaining on the watchdog timer
+
+        Returns:
+            An integer specifying the number of seconds remaining on
+            their watchdog timer. If the watchdog is not armed, returns
+            -1.
+
+            S5232 doesnot have hardware support to show remaining time.
+            Due to this limitation, this API is implemented in software.
+            This API would return correct software time difference if it
+            is called from the process which armed the watchdog timer.
+            If this API called from any other process, it would return
+            0. If the watchdog is not armed, this API would return -1.
+        """
+        if not self.is_armed():
+            return -1
+
+        if self.armed_time > 0 and self.timeout != 0:
+            cur_time = self._get_time()
+
+            if cur_time <= 0:
+                return 0
+
+            diff_time = int(cur_time - self.armed_time)
+
+            if diff_time > self.timeout:
+                return self.timeout
+            else:
+                return self.timeout - diff_time
+
+        return 0
+
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/systemd/platform-modules-n3248te.service b/platform/broadcom/sonic-platform-modules-dell/n3248te/systemd/platform-modules-n3248te.service
new file mode 100644
index 000000000000..403945f8c7f3
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/systemd/platform-modules-n3248te.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=Dell N3248TE Platform modules
+Before=pmon.service
+After=platform-init.service
+DefaultDependencies=no
+
+[Service]
+Type=oneshot
+ExecStart=/usr/local/bin/n3248te_platform.sh init
+ExecStop=/usr/local/bin/n3248te_platform.sh deinit
+RemainAfterExit=yes
+
+[Install]
+WantedBy=multi-user.target
diff --git a/src/sonic-device-data/tests/permitted_list b/src/sonic-device-data/tests/permitted_list
index 9ff0e5b6959f..4aabd19fdffa 100644
--- a/src/sonic-device-data/tests/permitted_list
+++ b/src/sonic-device-data/tests/permitted_list
@@ -257,3 +257,7 @@ appl_param_module_id
 serdes_lane_config_cl72_auto_polarity_en
 serdes_lane_config_cl72_restart_timeout_en
 bist_enable
+ifa_enable
+port_gmii_mode
+phy_force_firmware_load
+phy_pcs_repeater

From c89b67df42f29621881a436b67399b07f4ae7a21 Mon Sep 17 00:00:00 2001
From: Arun LK <Arun_L_K@dell.com>
Date: Wed, 22 Sep 2021 00:24:48 +0530
Subject: [PATCH 2/2] DellEMC: N3248TE Initial platform commit

---
 .../plugins/fanutil.py                        |  7 ++---
 .../plugins/sfputil.py                        |  4 ---
 .../n3248te/scripts/platform_sensors.py       |  3 --
 .../n3248te/scripts/portiocfg.py              |  1 -
 .../n3248te/scripts/ports_xcvrd_notify.py     |  6 ----
 .../n3248te/sonic_platform/chassis.py         |  3 +-
 .../n3248te/sonic_platform/component.py       |  2 --
 .../n3248te/sonic_platform/eeprom.py          |  2 +-
 .../n3248te/sonic_platform/fan.py             | 10 +++----
 .../n3248te/sonic_platform/psu.py             | 21 ++++++++------
 .../n3248te/sonic_platform/sfp.py             | 20 +++++--------
 .../n3248te/sonic_platform/thermal.py         |  3 +-
 .../n3248te/sonic_platform/watchdog.py        |  6 +---
 src/sonic-device-data/tests/permitted_list    | 29 +++++++++++++++++++
 14 files changed, 62 insertions(+), 55 deletions(-)

diff --git a/device/dell/x86_64-dellemc_n3248te_c3338-r0/plugins/fanutil.py b/device/dell/x86_64-dellemc_n3248te_c3338-r0/plugins/fanutil.py
index c8f277cb211b..47979b5d7ab5 100644
--- a/device/dell/x86_64-dellemc_n3248te_c3338-r0/plugins/fanutil.py
+++ b/device/dell/x86_64-dellemc_n3248te_c3338-r0/plugins/fanutil.py
@@ -3,8 +3,7 @@
 # Platform-specific FAN status interface for SONiC
 #
 
-import commands
-import os
+import subprocess
 import sys
 
 SENSORS_CMD = "docker exec -i pmon /usr/bin/sensors"
@@ -48,9 +47,9 @@ def get_direction(self, idx):
     def get_speed(self, idx):
         dockerenv = self.isDockerEnv()
         if not dockerenv:
-            status, cmd_output = commands.getstatusoutput(SENSORS_CMD)
+            status, cmd_output = subprocess.getstatusoutput(SENSORS_CMD)
         else :
-            status, cmd_output = commands.getstatusoutput(DOCKER_SENSORS_CMD)
+            status, cmd_output = subprocess.getstatusoutput(DOCKER_SENSORS_CMD)
 
         if status:
             print('Failed to execute sensors command')
diff --git a/device/dell/x86_64-dellemc_n3248te_c3338-r0/plugins/sfputil.py b/device/dell/x86_64-dellemc_n3248te_c3338-r0/plugins/sfputil.py
index 36df99d97591..1c974ca6fd00 100644
--- a/device/dell/x86_64-dellemc_n3248te_c3338-r0/plugins/sfputil.py
+++ b/device/dell/x86_64-dellemc_n3248te_c3338-r0/plugins/sfputil.py
@@ -5,10 +5,6 @@
 
 try:
     import time
-    import datetime
-    import os
-    import struct
-    import traceback
     from socket import *
     from select import *
     from sonic_sfp.sfputilbase import SfpUtilBase
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/platform_sensors.py
index 7756654a8219..02aa59595417 100755
--- a/platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/platform_sensors.py
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/platform_sensors.py
@@ -5,9 +5,6 @@
 #   * PSU
 
 
-import os
-import sys
-import logging
 import subprocess
 
 output = ""
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/portiocfg.py b/platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/portiocfg.py
index 10216af1d781..e81f8afa4470 100755
--- a/platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/portiocfg.py
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/portiocfg.py
@@ -64,7 +64,6 @@ def main(argv):
     opts = ''
     val = ''
     choice = ''
-    resouce = ''
     offset = ''
 
     try:
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/ports_xcvrd_notify.py b/platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/ports_xcvrd_notify.py
index 203d06e46cd3..c791590fb576 100755
--- a/platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/ports_xcvrd_notify.py
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/scripts/ports_xcvrd_notify.py
@@ -6,9 +6,6 @@
 """
 
 try:
-    import os
-    import sys
-    import time
     from datetime import datetime
     from swsscommon import swsscommon
     from sonic_py_common import daemon_base, logger
@@ -89,9 +86,6 @@ def main():
     helper_logger.log_notice("Start port_notify")
     # Connect to APP_DB and create transceiver dom info table
     appl_db = daemon_base.db_connect("APPL_DB")
-    cst = swsscommon.SubscriberStateTable(appl_db, swsscommon.APP_PORT_TABLE_NAME)
-
-    app_port_tbl = swsscommon.ProducerStateTable(appl_db, swsscommon.APP_PORT_TABLE_NAME)
 
     app_status_port_tbl = swsscommon.ProducerStateTable(appl_db,
                                                      swsscommon.APP_PORT_APP_STATUS_TABLE_NAME)
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/chassis.py
index e060f8028319..9686892f6f2a 100644
--- a/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/chassis.py
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/chassis.py
@@ -10,7 +10,6 @@
 
 try:
     import os
-    import select
     import sys
     import time
     from sonic_platform_base.chassis_base import ChassisBase
@@ -132,7 +131,7 @@ def _set_cpld_register(self, reg_name, value):
         try:
            with open(cpld_reg_file, 'w') as fd:
                 rv = fd.write(str(value))
-        except:
+        except Exception:
             rv = 'ERR'
 
         return rv
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/component.py
index 0fd3d8084da6..ec0dba2ab5b9 100644
--- a/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/component.py
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/component.py
@@ -10,8 +10,6 @@
 ########################################################################
 
 try:
-    import os
-    import re
     import subprocess
     from sonic_platform_base.component_base import ComponentBase
 
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/eeprom.py
index d2dc2f723108..75584cbc80b0 100644
--- a/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/eeprom.py
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/eeprom.py
@@ -28,7 +28,7 @@ def __init__(self):
         self.eeprom_tlv_dict = dict()
         try:
             self.eeprom_data = self.read_eeprom()
-        except:
+        except Exception:
             self.eeprom_data = "N/A"
             raise RuntimeError("Eeprom is not Programmed")
 
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/fan.py
index 0b23a5564790..873ae4163a84 100644
--- a/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/fan.py
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/fan.py
@@ -67,7 +67,7 @@ def get_model(self):
         """
         try:
             val = open(self.eeprom, "rb").read()[13:19]
-        except:
+        except Exception:
             val = None
         return val.decode()
 
@@ -79,7 +79,7 @@ def get_serial(self):
         """
         try:
             val = open(self.eeprom, "rb").read()[21:41]
-        except:
+        except Exception:
             val = None
         return val.decode()
 
@@ -124,7 +124,7 @@ def get_direction(self):
         else:
             try:
                 val = open(self.eeprom, "rb").read()[0xe1:0xe8]
-            except:
+            except Exception:
                 return None
             direction = 'Exhaust' if val == 'FORWARD' else 'Intake'
         return direction
@@ -145,7 +145,7 @@ def get_speed(self):
                 dps_dir = self.dps_hwmon + '/' + os.listdir(self.dps_hwmon)[0]
                 rpm_file = dps_dir + '/' + 'fan1_input'
             fan_speed = int(open(rpm_file, "rb").read())
-        except:
+        except Exception:
             return None
         speed = (100 * fan_speed)//self.max_speed
         return speed
@@ -164,6 +164,6 @@ def get_speed_rpm(self):
                 dps_dir = self.dps_hwmon + '/' + os.listdir(self.dps_hwmon)[0]
                 rpm_file = dps_dir + '/' + 'fan1_input'
             fan_speed = int(open(rpm_file, "rb").read())
-        except:
+        except Exception:
             return None
         return fan_speed
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/psu.py
index fb4167e67da7..30d4f2bd6c2a 100644
--- a/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/psu.py
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/psu.py
@@ -101,7 +101,8 @@ def get_model(self):
             string: Part number of PSU
         """
         try: val = open(self.eeprom, "rb").read()[0x50:0x62]
-        except: val = None
+        except Exception:
+            val = None
         return val.decode()
 
     def get_serial(self):
@@ -112,7 +113,8 @@ def get_serial(self):
             string: Serial number of PSU
         """
         try: val = open(self.eeprom, "rb").read()[0xc4:0xd9]
-        except: val = None
+        except Exception:
+            val = None
         return val.decode()
 
     def get_status(self):
@@ -134,11 +136,11 @@ def get_voltage(self):
             A float number, the output voltage in volts,
             e.g. 12.1
         """
-        voltage = 0.0
         volt_reading = self._get_dps_register(self.psu_voltage_reg)
         try:
             voltage = int(volt_reading)/1000
-        except : return None
+        except Exception:
+            return None
         return "{:.1f}".format(voltage)
 
     def get_current(self):
@@ -149,11 +151,11 @@ def get_current(self):
             A float number, electric current in amperes,
             e.g. 15.4
         """
-        current = 0.0
         curr_reading = self._get_dps_register(self.psu_current_reg)
         try:
             current = int(curr_reading)/1000
-        except : return None
+        except Exception:
+            return None
         return "{:.1f}".format(current)
 
     def get_power(self):
@@ -164,11 +166,11 @@ def get_power(self):
             A float number, the power in watts,
             e.g. 302.6
         """
-        power = 0.0
         power_reading = self._get_dps_register(self.psu_power_reg)
         try:
             power = int(power_reading)/1000
-        except : return None
+        except Exception:
+            return None
         return "{:.1f}".format(power)
 
     def get_powergood_status(self):
@@ -200,5 +202,6 @@ def get_type(self):
             A string, PSU power type
         """
         try: val = open(self.eeprom, "rb").read()[0xe8:0xea]
-        except: return None
+        except Exception:
+            return None
         return val
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/sfp.py
index b071460985f3..be10fd7d35b0 100644
--- a/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/sfp.py
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/sfp.py
@@ -10,19 +10,13 @@
 
 try:
     import os
-    import time
     import struct
-    import sys
-    import getopt
-    import select
     import mmap
-    from sonic_platform_base.chassis_base import ChassisBase
     from sonic_platform_base.sfp_base import SfpBase
     from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId
     from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom
     from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId
     from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom
-    from sonic_platform_base.sonic_sfp.sff8472 import sffbase
 
 except ImportError as e:
     raise ImportError(str(e) + "- required module not found")
@@ -539,7 +533,8 @@ def get_presence(self):
             sfp_mod_prs = self._get_cpld_register('sfp_modprs')
             if sfp_mod_prs == 'ERR' : return presence
             presence =  ((int(sfp_mod_prs, 16) & bit_mask) == 0)
-        except: pass
+        except Exception:
+            pass
         return presence
 
     def get_model(self):
@@ -584,7 +579,8 @@ def get_rx_los(self):
             sfp_rxlos = self._get_cpld_register('sfp_rxlos')
             if sfp_rxlos == 'ERR' : return rx_los
             rx_los =  ((int(sfp_rxlos, 16) & bit_mask) != 0)
-        except: pass
+        except Exception:
+            pass
         return rx_los
 
     def get_tx_fault(self):
@@ -598,7 +594,8 @@ def get_tx_fault(self):
             sfp_txfault = self._get_cpld_register('sfp_txfault')
             if sfp_txfault == 'ERR' : return tx_fault
             tx_fault =  ((int(sfp_txfault, 16) & bit_mask) != 0)
-        except: pass
+        except Exception:
+            pass
         return tx_fault
 
     def get_tx_disable(self):
@@ -612,7 +609,8 @@ def get_tx_disable(self):
             sfp_txdisable = self._get_cpld_register('sfp_txdis')
             if sfp_txdisable == 'ERR' : return tx_disable
             tx_disable =  ((int(sfp_txdisable, 16) & bit_mask) != 0)
-        except: pass
+        except Exception:
+            pass
         return tx_disable
 
     def get_tx_disable_channel(self):
@@ -655,7 +653,6 @@ def get_temperature(self):
         """
         Retrieves the temperature of this SFP
         """
-        temperature = 'N/A'
         try :
             temperature_data = self._get_eeprom_data('Temperature')
             temperature = temperature_data['data']['Temperature']['value']
@@ -667,7 +664,6 @@ def get_voltage(self):
         """
         Retrieves the supply voltage of this SFP
         """
-        voltage = 'N/A'
         try:
             voltage_data = self._get_eeprom_data('Voltage')
             voltage = voltage_data['data']['Vcc']['value']
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/thermal.py
index cdbd74562392..96edda7c14d4 100644
--- a/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/thermal.py
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/thermal.py
@@ -91,7 +91,8 @@ def get_temperature(self):
         temperature = 0.0
         try :
             temperature = float(open(self.temp_file).read()) / 1000.0
-        except : pass
+        except Exception:
+            pass
         return float(temperature)
 
     def get_high_threshold(self):
diff --git a/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/watchdog.py
index 90a6c7f6eef4..ebd4706b4215 100644
--- a/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/watchdog.py
+++ b/platform/broadcom/sonic-platform-modules-dell/n3248te/sonic_platform/watchdog.py
@@ -2,7 +2,7 @@
 
 ########################################################################
 #
-# DELLEMC Z9332F
+# DELLEMC N3248TE
 #
 # Abstract base class for implementing a platform-specific class with
 # which to interact with a hardware watchdog module in SONiC
@@ -10,8 +10,6 @@
 ########################################################################
 
 try:
-    import sys
-    import struct
     import ctypes
     import subprocess
     from sonic_platform_base.watchdog_base import WatchdogBase
@@ -139,8 +137,6 @@ def arm(self, seconds):
             self.timeout = seconds
             return seconds
 
-        return -1
-
     def disarm(self):
         """
         Disarm the hardware watchdog
diff --git a/src/sonic-device-data/tests/permitted_list b/src/sonic-device-data/tests/permitted_list
index 4aabd19fdffa..a22d530d1256 100644
--- a/src/sonic-device-data/tests/permitted_list
+++ b/src/sonic-device-data/tests/permitted_list
@@ -257,6 +257,35 @@ appl_param_module_id
 serdes_lane_config_cl72_auto_polarity_en
 serdes_lane_config_cl72_restart_timeout_en
 bist_enable
+mmu_config_override
+buf.prigroup.guarantee
+buf.prigroup.device_headroom_enable
+buf.prigroup.pool_resume
+buf.prigroup.pool_scale
+buf.prigroup.port_guarantee_enable
+buf.prigroup.port_max_enable
+buf.prigroup.flow_control_enable
+buf.queue.pool_scale
+buf.mqueue.pool_scale
+buf.queue.pool_scale
+buf.mqueue.pool_scale
+buf.mqueue.pool_scale_cpu
+buf.queue.qgroup_guarantee_enable
+profile_pg_1hdrm_8shared
+buf.map.pri.prigroup
+udp_port
+multi_hash_recurse_depth_exact_match
+robust_hash_seed_exact_match
+my_udp_port_int
+server_udp_port_int
+probe_marker1_int
+probe_marker2_int
+hoplimit_int
+lb_port_pipe0_int
+lb_port_pipe1_int
+ing_origin_id_device_id_mask
+egr_origin_id_device_id_mask
+port_count_in_pb_stream
 ifa_enable
 port_gmii_mode
 phy_force_firmware_load