summaryrefslogtreecommitdiff
path: root/meta-ampere/meta-common/recipes-ac01
diff options
context:
space:
mode:
Diffstat (limited to 'meta-ampere/meta-common/recipes-ac01')
-rw-r--r--meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl.bb85
-rw-r--r--meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-chassis-poweroff.service11
-rw-r--r--meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-chassis-poweron.service9
-rw-r--r--meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-force-reset.service11
-rw-r--r--meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-power-cycle.service10
-rw-r--r--meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-reset-ack.service10
-rw-r--r--meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-reset.service9
-rw-r--r--meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-shutdown.service10
-rw-r--r--meta-ampere/meta-common/recipes-ac01/host/files/ampere_power_util.sh109
-rw-r--r--meta-ampere/meta-common/recipes-ac01/host/files/obmc/gpio/reboot_ack4
-rw-r--r--meta-ampere/meta-common/recipes-ac01/host/files/obmc/gpio/shutdown_ack4
-rw-r--r--meta-ampere/meta-common/recipes-ac01/mac/ampere-mac-update.bb26
-rw-r--r--meta-ampere/meta-common/recipes-ac01/mac/ampere-mac-update/ampere_update_mac.service12
-rw-r--r--meta-ampere/meta-common/recipes-ac01/mac/ampere-mac-update/ampere_update_mac.sh43
-rw-r--r--meta-ampere/meta-common/recipes-ac01/packagegroups/packagegroup-ampere-apps.bb38
-rw-r--r--meta-ampere/meta-common/recipes-ac01/usbnet/ampere-usbnet.bb30
-rw-r--r--meta-ampere/meta-common/recipes-ac01/usbnet/ampere-usbnet/00-bmc-usb0.network7
-rw-r--r--meta-ampere/meta-common/recipes-ac01/usbnet/ampere-usbnet/ampere_add_usbnet_gadget.service13
-rw-r--r--meta-ampere/meta-common/recipes-ac01/usbnet/ampere-usbnet/ampere_add_usbnet_gadget.sh93
19 files changed, 534 insertions, 0 deletions
diff --git a/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl.bb b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl.bb
new file mode 100644
index 000000000..e7c3cc160
--- /dev/null
+++ b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl.bb
@@ -0,0 +1,85 @@
+SUMMARY = "Ampere Computing LLC Host Control Implementation"
+DESCRIPTION = "A host control implementation suitable for Ampere Computing LLC's systems"
+PR = "r1"
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
+
+inherit systemd
+inherit obmc-phosphor-systemd
+
+# For now, monitoring shutdown_ack and reboot_ack are the only usecases
+OBMC_HOST_MONITOR_INSTANCES = "shutdown_ack reboot_ack"
+SYSTEMD_ENVIRONMENT_FILE_${PN} +="obmc/gpio/shutdown_ack obmc/gpio/reboot_ack"
+
+S = "${WORKDIR}"
+
+SRC_URI = "file://ampere-host-shutdown.service \
+ file://ampere-host-reset.service \
+ file://ampere_power_util.sh \
+ file://ampere-chassis-poweroff.service \
+ file://ampere-chassis-poweron.service \
+ file://ampere-host-reset-ack.service \
+ file://ampere-host-force-reset.service \
+ file://ampere-host-power-cycle.service \
+ "
+
+DEPENDS = "systemd virtual/obmc-gpio-monitor"
+RDEPENDS_${PN} = "bash virtual/obmc-gpio-monitor"
+
+SYSTEMD_PACKAGES = "${PN}"
+SYSTEMD_SERVICE_${PN} = " \
+ ampere-host-shutdown.service \
+ ampere-host-reset.service \
+ ampere-chassis-poweroff.service \
+ ampere-chassis-poweron.service \
+ ampere-host-reset-ack.service \
+ ampere-host-force-reset.service \
+ ampere-host-power-cycle.service \
+ "
+# host power control
+# overwrite the host shutdown to graceful shutdown
+HOST_SHUTDOWN_TMPL = "ampere-host-shutdown.service"
+HOST_SHUTDOWN_TGTFMT = "obmc-host-shutdown@{0}.target"
+HOST_SHUTDOWN_FMT = "../${HOST_SHUTDOWN_TMPL}:${HOST_SHUTDOWN_TGTFMT}.requires/${HOST_SHUTDOWN_TMPL}"
+SYSTEMD_LINK_${PN} += "${@compose_list_zip(d, 'HOST_SHUTDOWN_FMT', 'OBMC_HOST_INSTANCES')}"
+
+# Force the power cycle target to run the ampere power cycle
+HOST_REBOOT_SVC = "ampere-host-power-cycle.service"
+HOST_REBOOT_SVC_TGTFMT = "obmc-host-reboot@{0}.target"
+HOST_REBOOT_SVC_FMT = "../${HOST_REBOOT_SVC}:${HOST_REBOOT_SVC_TGTFMT}.requires/${HOST_REBOOT_SVC}"
+SYSTEMD_LINK_${PN} += "${@compose_list_zip(d, 'HOST_REBOOT_SVC_FMT', 'OBMC_HOST_INSTANCES')}"
+
+# overwrite the host reset to graceful reset
+HOST_WARM_REBOOT_SOFT_SVC = "ampere-host-reset.service"
+HOST_WARM_REBOOT_TGTFMT = "obmc-host-warm-reboot@{0}.target"
+HOST_WARM_REBOOT_SOFT_SVC_FMT = "../${HOST_WARM_REBOOT_SOFT_SVC}:${HOST_WARM_REBOOT_TGTFMT}.requires/${HOST_WARM_REBOOT_SOFT_SVC}"
+SYSTEMD_LINK_${PN} += "${@compose_list_zip(d, 'HOST_WARM_REBOOT_SOFT_SVC_FMT', 'OBMC_HOST_INSTANCES')}"
+
+# overwrite force reboot
+HOST_WARM_REBOOT_FORCE_TGT = "ampere-host-force-reset.service"
+HOST_WARM_REBOOT_FORCE_TGTFMT = "obmc-host-force-warm-reboot@{0}.target"
+HOST_WARM_REBOOT_FORCE_TARGET_FMT = "../${HOST_WARM_REBOOT_FORCE_TGT}:${HOST_WARM_REBOOT_FORCE_TGTFMT}.requires/${HOST_WARM_REBOOT_FORCE_TGT}"
+SYSTEMD_LINK_${PN} += "${@compose_list_zip(d, 'HOST_WARM_REBOOT_FORCE_TARGET_FMT', 'OBMC_HOST_INSTANCES')}"
+
+# chassis power control
+CHASSIS_POWERON_SVC = "ampere-chassis-poweron.service"
+CHASSIS_POWERON_TGTFMT = "obmc-chassis-poweron@{0}.target"
+CHASSIS_POWERON_FMT = "../${CHASSIS_POWERON_SVC}:${CHASSIS_POWERON_TGTFMT}.requires/${CHASSIS_POWERON_SVC}"
+SYSTEMD_LINK_${PN} += "${@compose_list_zip(d, 'CHASSIS_POWERON_FMT', 'OBMC_CHASSIS_INSTANCES')}"
+
+CHASSIS_POWEROFF_SVC = "ampere-chassis-poweroff.service"
+CHASSIS_POWEROFF_TGTFMT = "obmc-chassis-poweroff@{0}.target"
+CHASSIS_POWEROFF_FMT = "../${CHASSIS_POWEROFF_SVC}:${CHASSIS_POWEROFF_TGTFMT}.requires/${CHASSIS_POWEROFF_SVC}"
+SYSTEMD_LINK_${PN} += "${@compose_list_zip(d, 'CHASSIS_POWEROFF_FMT', 'OBMC_CHASSIS_INSTANCES')}"
+
+TMPL = "phosphor-gpio-monitor@.service"
+INSTFMT = "phosphor-gpio-monitor@{0}.service"
+TGT = "multi-user.target"
+FMT = "../${TMPL}:${TGT}.requires/${INSTFMT}"
+SYSTEMD_LINK_${PN} += "${@compose_list(d, 'FMT', 'OBMC_HOST_MONITOR_INSTANCES')}"
+
+do_install() {
+ install -d ${D}/usr/sbin
+ install -m 0755 ${WORKDIR}/ampere_power_util.sh ${D}/${sbindir}/ampere_power_util.sh
+}
+
diff --git a/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-chassis-poweroff.service b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-chassis-poweroff.service
new file mode 100644
index 000000000..b0a1af785
--- /dev/null
+++ b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-chassis-poweroff.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=Ampere Computing LLC Power OFF Chassis
+Requires=op-wait-power-off@%i.service
+Before=op-wait-power-off@%i.service
+Conflicts=obmc-chassis-poweron@0.target
+
+[Service]
+RemainAfterExit=no
+Type=oneshot
+ExecStart=/usr/bin/env ampere_power_util.sh mb off
+SyslogIdentifier=ampere_power_util.sh
diff --git a/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-chassis-poweron.service b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-chassis-poweron.service
new file mode 100644
index 000000000..76ceb8856
--- /dev/null
+++ b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-chassis-poweron.service
@@ -0,0 +1,9 @@
+[Unit]
+Description=Ampere Computing LLC Power ON Chassis
+Conflicts=obmc-chassis-poweroff@0.target
+
+[Service]
+RemainAfterExit=yes
+Type=oneshot
+ExecStart=/usr/bin/env ampere_power_util.sh mb on
+SyslogIdentifier=ampere_power_util.sh
diff --git a/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-force-reset.service b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-force-reset.service
new file mode 100644
index 000000000..8a40baf7b
--- /dev/null
+++ b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-force-reset.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=Ampere Computing LLC force reset host
+Conflicts=obmc-chassis-poweroff@0.target
+OnFailure=obmc-chassis-powerreset@0.target
+
+[Service]
+RemainAfterExit=no
+Type=oneshot
+ExecStart=/usr/bin/env ampere_power_util.sh mb force_reset
+SyslogIdentifier=ampere_power_util.sh
+
diff --git a/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-power-cycle.service b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-power-cycle.service
new file mode 100644
index 000000000..2fb03effb
--- /dev/null
+++ b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-power-cycle.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=Ampere Computing LLC power cycle service
+Conflicts=obmc-host-start@0.target
+OnFailure=obmc-chassis-powerreset@0.target
+
+[Service]
+RemainAfterExit=no
+Type=oneshot
+ExecStart=/usr/bin/env ampere_power_util.sh mb cycle
+SyslogIdentifier=ampere_power_util.sh
diff --git a/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-reset-ack.service b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-reset-ack.service
new file mode 100644
index 000000000..504186ec6
--- /dev/null
+++ b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-reset-ack.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=Ampere Computing LLC triggering reset ACK
+Conflicts=obmc-host-start@0.target
+OnFailure=obmc-chassis-powerreset@0.target
+
+[Service]
+RemainAfterExit=no
+Type=oneshot
+ExecStart=/usr/bin/env ampere_power_util.sh mb force_reset
+SyslogIdentifier=ampere_power_util.sh
diff --git a/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-reset.service b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-reset.service
new file mode 100644
index 000000000..ac7618ad0
--- /dev/null
+++ b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-reset.service
@@ -0,0 +1,9 @@
+[Unit]
+Description=Ampere Computing LLC warm reset host
+Conflicts=obmc-chassis-poweroff@0.target
+
+[Service]
+RemainAfterExit=no
+Type=oneshot
+ExecStart=/usr/bin/env ampere_power_util.sh mb graceful_reset
+SyslogIdentifier=ampere_power_util.sh
diff --git a/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-shutdown.service b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-shutdown.service
new file mode 100644
index 000000000..be4d45260
--- /dev/null
+++ b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-shutdown.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=Ampere Computing LLC graceful shutdown host
+Conflicts=obmc-host-start@0.target
+OnFailure=obmc-chassis-poweroff@0.target
+
+[Service]
+RemainAfterExit=no
+Type=oneshot
+ExecStart=/usr/bin/env ampere_power_util.sh mb graceful_shutdown
+SyslogIdentifier=ampere_power_util.sh
diff --git a/meta-ampere/meta-common/recipes-ac01/host/files/ampere_power_util.sh b/meta-ampere/meta-common/recipes-ac01/host/files/ampere_power_util.sh
new file mode 100644
index 000000000..8bab9a370
--- /dev/null
+++ b/meta-ampere/meta-common/recipes-ac01/host/files/ampere_power_util.sh
@@ -0,0 +1,109 @@
+#!/bin/bash
+# Usage of this utility
+function usage() {
+ echo "usage: power-util mb [on|off|status|cycle|reset|graceful_shutdown|graceful_reset|force_reset]";
+}
+
+power_off() {
+ echo "Shutting down Server $2"
+ busctl set-property xyz.openbmc_project.State.Chassis /xyz/openbmc_project/state/chassis0 xyz.openbmc_project.State.Chassis RequestedPowerTransition s xyz.openbmc_project.State.Chassis.Transition.Off
+}
+
+power_on() {
+ echo "Powering on Server $2"
+ busctl set-property xyz.openbmc_project.State.Chassis /xyz/openbmc_project/state/chassis0 xyz.openbmc_project.State.Chassis RequestedPowerTransition s xyz.openbmc_project.State.Chassis.Transition.On
+}
+
+power_status() {
+ st=$(busctl get-property xyz.openbmc_project.State.Chassis /xyz/openbmc_project/state/chassis0 xyz.openbmc_project.State.Chassis CurrentPowerState | cut -d"." -f6)
+ if [ "$st" == "On\"" ]; then
+ echo "on"
+ else
+ echo "off"
+ fi
+}
+
+power_reset() {
+ echo "Reset on server $2"
+ busctl set-property xyz.openbmc_project.State.Host /xyz/openbmc_project/state/host0 xyz.openbmc_project.State.Host RequestedHostTransition s xyz.openbmc_project.State.Host.Transition.Reboot
+}
+
+graceful_shutdown() {
+ if [ -f "/run/openbmc/host@0-request" ]; then
+ echo "shutdown host immediately"
+ power_off
+ else
+ echo "Triggering graceful shutdown"
+ gpioset -l 0 49=1
+ sleep 1
+ gpioset -l 0 49=0
+ sleep 30s
+ fi
+}
+
+force_reset() {
+ echo "Triggering sysreset pin"
+ gpioset -l 0 91=1
+ sleep 1
+ gpioset -l 0 91=0
+}
+
+if [ $# -lt 2 ]; then
+ echo "Total number of parameter=$#"
+ echo "Insufficient parameter"
+ usage;
+ exit 0;
+fi
+
+if [ $1 != "mb" ]; then
+ echo "Invalid parameter1=$1"
+ usage;
+ exit 0;
+fi
+
+if [ $2 = "on" ]; then
+ if [ $(power_status) == "off" ]; then
+ power_on
+ fi
+elif [ $2 = "off" ]; then
+ if [ $(power_status) == "on" ]; then
+ power_off
+ fi
+ # If any request of graceful reset, need to power on
+ if [ -f "/run/openbmc/host@0-graceful-reset" ]; then
+ sleep 20s
+ power_on
+ rm -f "/run/openbmc/host@0-graceful-reset"
+ fi
+elif [ $2 == "cycle" ]; then
+ if [ $(power_status) == "on" ]; then
+ echo "Powering off server"
+ power_off
+ sleep 20s
+ power_on
+ else
+ echo "Host is already off, do nothing"
+ fi
+elif [ $2 == "reset" ]; then
+ if [ $(power_status) == "on" ]; then
+ power_reset
+ else
+ echo "ERROR: Server not powered on"
+ fi
+elif [[ $2 == "graceful_shutdown" ]]; then
+ graceful_shutdown
+elif [ $2 == "graceful_reset" ]; then
+ mkdir -p "/run/openbmc/"
+ touch "/run/openbmc/host@0-graceful-reset"
+ graceful_shutdown
+ sleep 20s
+elif [ $2 == "status" ]; then
+ power_status
+elif [ $2 == "force_reset" ]; then
+ force_reset
+else
+ echo "Invalid parameter2=$2"
+ usage;
+fi
+
+exit 0;
diff --git a/meta-ampere/meta-common/recipes-ac01/host/files/obmc/gpio/reboot_ack b/meta-ampere/meta-common/recipes-ac01/host/files/obmc/gpio/reboot_ack
new file mode 100644
index 000000000..0436d32da
--- /dev/null
+++ b/meta-ampere/meta-common/recipes-ac01/host/files/obmc/gpio/reboot_ack
@@ -0,0 +1,4 @@
+DEVPATH=/dev/input/event0
+KEY=75
+POLARITY=1
+TARGET=ampere-host-reset-ack.service
diff --git a/meta-ampere/meta-common/recipes-ac01/host/files/obmc/gpio/shutdown_ack b/meta-ampere/meta-common/recipes-ac01/host/files/obmc/gpio/shutdown_ack
new file mode 100644
index 000000000..a0e857fac
--- /dev/null
+++ b/meta-ampere/meta-common/recipes-ac01/host/files/obmc/gpio/shutdown_ack
@@ -0,0 +1,4 @@
+DEVPATH=/dev/input/event0
+KEY=50
+POLARITY=1
+TARGET=ampere-chassis-poweroff.service
diff --git a/meta-ampere/meta-common/recipes-ac01/mac/ampere-mac-update.bb b/meta-ampere/meta-common/recipes-ac01/mac/ampere-mac-update.bb
new file mode 100644
index 000000000..3e18ad71e
--- /dev/null
+++ b/meta-ampere/meta-common/recipes-ac01/mac/ampere-mac-update.bb
@@ -0,0 +1,26 @@
+SUMMARY = "Ampere Computing LLC Update MAC Address from FRU Inventory Information"
+DESCRIPTION = "Update MAC Address from FRU Inventory Information for Ampere systems"
+PR = "r1"
+
+LICENSE = "Apache-2.0"
+
+LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
+
+inherit systemd
+inherit obmc-phosphor-systemd
+
+DEPENDS = "systemd"
+RDEPENDS_${PN} = "bash"
+
+FILESEXTRAPATHS_append := "${THISDIR}/${PN}:"
+
+SRC_URI += " \
+ file://ampere_update_mac.sh \
+ "
+
+SYSTEMD_SERVICE_${PN} = "ampere_update_mac.service"
+
+do_install_append() {
+ install -d ${D}/${sbindir}
+ install -m 755 ${WORKDIR}/ampere_update_mac.sh ${D}/${sbindir}
+}
diff --git a/meta-ampere/meta-common/recipes-ac01/mac/ampere-mac-update/ampere_update_mac.service b/meta-ampere/meta-common/recipes-ac01/mac/ampere-mac-update/ampere_update_mac.service
new file mode 100644
index 000000000..86f7a0346
--- /dev/null
+++ b/meta-ampere/meta-common/recipes-ac01/mac/ampere-mac-update/ampere_update_mac.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=Updating MAC Address Service From FRU inventory
+After=xyz.openbmc_project.Inventory.Manager.service
+
+[Service]
+ExecStart=/usr/sbin/ampere_update_mac.sh
+SyslogIdentifier=ampere_update_mac.sh
+Type=oneshot
+RemainAfterExit=yes
+
+[Install]
+WantedBy={SYSTEMD_DEFAULT_TARGET}
diff --git a/meta-ampere/meta-common/recipes-ac01/mac/ampere-mac-update/ampere_update_mac.sh b/meta-ampere/meta-common/recipes-ac01/mac/ampere-mac-update/ampere_update_mac.sh
new file mode 100644
index 000000000..5dbdde771
--- /dev/null
+++ b/meta-ampere/meta-common/recipes-ac01/mac/ampere-mac-update/ampere_update_mac.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+#
+# This script is used to get the MAC Address from FRU Inventory information
+
+ETHERNET_INTERFACE="eth0"
+ENV_ETH="eth1addr"
+ENV_MAC_ADDR=`fw_printenv`
+
+# Check if BMC MAC address is exported
+if [[ $ENV_MAC_ADDR =~ $ENV_ETH ]]; then
+ echo "WARNING: BMC MAC address already exist!"
+ exit 0
+fi
+
+# Read FRU Board Custom Field 1 to get the MAC address
+CUSTOM_FIELD_1=`busctl get-property xyz.openbmc_project.Inventory.Manager /xyz/openbmc_project/inventory/system/chassis/motherboard xyz.openbmc_project.Inventory.Item.NetworkInterface MACAddress`
+MAC_ADDR=`echo $CUSTOM_FIELD_1 | cut -d "\"" -f 2`
+
+# Check if BMC MAC address is exported
+if [ -z "${MAC_ADDR}" ]; then
+ echo "ERROR: No BMC MAC address is detected from FRU Inventory information!"
+ # Return 1 so that systemd knows the service failed to start
+ exit 1
+fi
+
+# Request to update the MAC address
+fw_setenv ${ENV_ETH} ${MAC_ADDR}
+
+if [[ $? -ne 0 ]]; then
+ echo "ERROR: Fail to set MAC address to ${ENV_ETH}"
+ exit 1
+fi
+
+# Request to restart the service
+ifconfig ${ETHERNET_INTERFACE} down
+ifconfig ${ETHERNET_INTERFACE} hw ether ${MAC_ADDR}
+if [[ $? -ne 0 ]]; then
+ echo "ERROR: Can not update MAC ADDR to ${ETHERNET_INTERFACE}"
+ exit 1
+fi
+ifconfig ${ETHERNET_INTERFACE} up
+
+echo "Successfully update the MAC address ${MAC_ADDR} to ${ENV_ETH} and ${ETHERNET_INTERFACE}"
diff --git a/meta-ampere/meta-common/recipes-ac01/packagegroups/packagegroup-ampere-apps.bb b/meta-ampere/meta-common/recipes-ac01/packagegroups/packagegroup-ampere-apps.bb
new file mode 100644
index 000000000..d29b87083
--- /dev/null
+++ b/meta-ampere/meta-common/recipes-ac01/packagegroups/packagegroup-ampere-apps.bb
@@ -0,0 +1,38 @@
+SUMMARY = "OpenBMC for Ampere - Applications"
+PR = "r1"
+
+inherit packagegroup
+inherit obmc-phosphor-utils
+
+PROVIDES = "${PACKAGES}"
+PACKAGES = " \
+ ${PN}-chassis \
+ ${PN}-flash \
+ ${PN}-system \
+ "
+
+PROVIDES += "virtual/obmc-chassis-mgmt"
+PROVIDES += "virtual/obmc-flash-mgmt"
+PROVIDES += "virtual/obmc-system-mgmt"
+
+RPROVIDES_${PN}-chassis += "virtual-obmc-chassis-mgmt"
+RPROVIDES_${PN}-flash += "virtual-obmc-flash-mgmt"
+RPROVIDES_${PN}-system += "virtual-obmc-system-mgmt"
+
+SUMMARY_${PN}-chassis = "Ampere Chassis"
+RDEPENDS_${PN}-chassis = " \
+ obmc-op-control-power \
+ ampere-hostctrl \
+ phosphor-hostlogger \
+ phosphor-sel-logger \
+ phosphor-logging \
+ "
+
+SUMMARY_${PN}-system = "Ampere System"
+RDEPENDS_${PN}-system = " \
+ "
+
+SUMMARY_${PN}-flash = "Ampere Flash"
+RDEPENDS_${PN}-flash = " \
+ ampere-flash-utils \
+ "
diff --git a/meta-ampere/meta-common/recipes-ac01/usbnet/ampere-usbnet.bb b/meta-ampere/meta-common/recipes-ac01/usbnet/ampere-usbnet.bb
new file mode 100644
index 000000000..f683f8015
--- /dev/null
+++ b/meta-ampere/meta-common/recipes-ac01/usbnet/ampere-usbnet.bb
@@ -0,0 +1,30 @@
+SUMMARY = "Ampere Computing LLC Add Ethernet over USB gadget device"
+DESCRIPTION = "Add Ethernet over USB gadget device for Ampere systems"
+PR = "r1"
+
+LICENSE = "Apache-2.0"
+S = "${WORKDIR}"
+
+LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
+
+inherit systemd
+inherit obmc-phosphor-systemd
+
+DEPENDS = "systemd"
+RDEPENDS_${PN} = "bash"
+
+SYSTEMD_PACKAGES = "${PN}"
+SYSTEMD_SERVICE_${PN} = " \
+ ampere_add_usbnet_gadget.service \
+ "
+
+SRC_URI += "file://00-bmc-usb0.network"
+SRC_URI += "file://ampere_add_usbnet_gadget.sh"
+
+do_install_append() {
+ install -d ${D}${sbindir}
+ install -d ${D}/etc/systemd/network
+ install -m 744 ${WORKDIR}/ampere_add_usbnet_gadget.sh ${D}${sbindir}/
+ install -m 644 ${WORKDIR}/00-bmc-usb0.network \
+ ${D}/etc/systemd/network/
+}
diff --git a/meta-ampere/meta-common/recipes-ac01/usbnet/ampere-usbnet/00-bmc-usb0.network b/meta-ampere/meta-common/recipes-ac01/usbnet/ampere-usbnet/00-bmc-usb0.network
new file mode 100644
index 000000000..640fe04b9
--- /dev/null
+++ b/meta-ampere/meta-common/recipes-ac01/usbnet/ampere-usbnet/00-bmc-usb0.network
@@ -0,0 +1,7 @@
+[Match]
+Name=usb0
+[Address]
+Address=192.168.0.10/16
+[Network]
+LinkLocalAddressing=no
+IPv6AcceptRA=no
diff --git a/meta-ampere/meta-common/recipes-ac01/usbnet/ampere-usbnet/ampere_add_usbnet_gadget.service b/meta-ampere/meta-common/recipes-ac01/usbnet/ampere-usbnet/ampere_add_usbnet_gadget.service
new file mode 100644
index 000000000..428263a89
--- /dev/null
+++ b/meta-ampere/meta-common/recipes-ac01/usbnet/ampere-usbnet/ampere_add_usbnet_gadget.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=Ampere adds Ethernet over USB gadget device
+Wants=systemd-networkd.service
+Before=systemd-networkd.service
+After=phosphor-ipmi-host.service
+
+[Service]
+ExecStart=/usr/bin/env ampere_add_usbnet_gadget.sh
+SyslogIdentifier=ampere_add_usbnet_gadget.sh
+Type=oneshot
+
+[Install]
+WantedBy=systemd-networkd.service
diff --git a/meta-ampere/meta-common/recipes-ac01/usbnet/ampere-usbnet/ampere_add_usbnet_gadget.sh b/meta-ampere/meta-common/recipes-ac01/usbnet/ampere-usbnet/ampere_add_usbnet_gadget.sh
new file mode 100644
index 000000000..c4c2c273f
--- /dev/null
+++ b/meta-ampere/meta-common/recipes-ac01/usbnet/ampere-usbnet/ampere_add_usbnet_gadget.sh
@@ -0,0 +1,93 @@
+#!/bin/sh
+
+# Add an Ethernet over USB gadget device and connect to a port of Aspeed USB
+# virtual hub. If can't find any free port on virtual hub, exit with failure.
+# If can't find the virtual hub, exit with failure.
+
+# Author: Thinh Hung Pham <thinh.pham@amperecomputing.com>
+# Signed-off-by: Chanh Nguyen <chnguyen@amperecomputing.com>
+
+UDC_SYSPATH=/sys/class/udc
+VHUB_DEVICE=1e6a0000.usb-vhub:p
+GADGET_CONFIG_SYSPATH=/sys/kernel/config/usb_gadget
+USBNET=usbnet
+# The number of port on AST2500 USB virtual hub
+NUM_PORT_USB_HUB=5
+# idVendor = 0x1d6b: Linux Foundation
+VENDORID=0x1d6b
+# idProduct = 0x0103: NCM (Ethernet) Gadget
+PRODUCTID=0x0103
+# Language code = 0x409: English – United States
+LANGUAGEID=0x409
+SERIALNUMBER=cafecafe
+MANUFACTURER=Aspeed
+FUNCTION=ecm.usb0
+
+if [ ! -d ${GADGET_CONFIG_SYSPATH} ]; then
+ # GADGET_CONFIG_SYSPATH is not exist
+ # Return 1 so that systemd knows the service failed to start
+ echo "ERROR: ${GADGET_CONFIG_SYSPATH} : doesn't exist!"
+ exit 1
+fi
+
+find_free_vhub_port(){
+ for ((i=1;i<=${NUM_PORT_USB_HUB};i++))
+ do
+ state=$(cat ${UDC_SYSPATH}/${VHUB_DEVICE}${i}/state)
+ func=$(cat ${UDC_SYSPATH}/${VHUB_DEVICE}${i}/function)
+ if [ "${state}" == "not attached" -a "${func}" == "" ]; then
+ FREEUDC=${VHUB_DEVICE}${i}
+ break
+ fi
+ done
+ if [ ${i} -eq 6 ]; then
+ # Can't find a free port
+ # Return 1 so that systemd knows the service failed to start
+ echo "ERROR: Can't find a free port !"
+ exit 1
+ fi
+}
+
+if [ -d ${GADGET_CONFIG_SYSPATH}/${USBNET} ]; then
+ cd ${GADGET_CONFIG_SYSPATH}/${USBNET}
+else
+ # Create the gadget
+ mkdir ${GADGET_CONFIG_SYSPATH}/${USBNET}
+ cd ${GADGET_CONFIG_SYSPATH}/${USBNET}
+
+ # Configure the gadget
+ echo ${VENDORID} > idVendor
+ echo ${PRODUCTID} > idProduct
+ mkdir strings/${LANGUAGEID}
+ echo ${SERIALNUMBER} > strings/${LANGUAGEID}/serialnumber
+ echo ${MANUFACTURER} > strings/${LANGUAGEID}/manufacturer
+ echo ${USBNET} > strings/${LANGUAGEID}/product
+
+ # Create the configuration
+ mkdir configs/c.1
+ mkdir configs/c.1/strings/${LANGUAGEID}
+
+ # Create the function
+ mkdir functions/${FUNCTION}
+
+ # Associate the function with its configuration
+ ln -s functions/${FUNCTION} configs/c.1
+fi
+
+# Find an available virtual hub port
+find_free_vhub_port
+
+# Enable the gadget
+echo ${FREEUDC} > UDC
+
+if [[ $? -ne 0 ]]; then
+ # End
+ cd - > /dev/null
+ # Virtual HUB is not available
+ # Return 1 so that systemd knows the service failed to start
+ exit 1
+fi
+
+# End
+cd - > /dev/null
+