initial version with minimal support
authorMugunthan V N <mugunthanvnm@ti.com>
Tue, 28 Oct 2014 16:56:07 +0000 (22:26 +0530)
committerMugunthan V N <mugunthanvnm@ti.com>
Wed, 29 Oct 2014 12:20:12 +0000 (17:50 +0530)
Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
Makefile [new file with mode: 0644]
README [new file with mode: 0644]
switch-config.c [new file with mode: 0644]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..2ad3485
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,33 @@
+# Makefile for switch-config
+
+CC             =       $(CROSS_COMPILE)gcc
+KBUILD_OUTPUT  ?=      /lib/modules/$(shell uname -r)/build
+CFLAGS         =       -I$(KBUILD_OUTPUT)/usr/include
+
+GIT_VERSION := $(shell git describe --dirty --always)
+RM = rm -f
+CFLAGS+= -Wall -DVERSION=\"$(GIT_VERSION)\"
+LDFLAGS+=
+
+PROG = switch-config
+SRCS = switch-config.c
+
+OBJS = $(SRCS:.c=.o)
+
+HDRS =
+
+.c.o:
+       $(CC) -c $(CFLAGS) -o $@ $<
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+       $(CC) $(LDFLAGS) -o $@ $(OBJS)
+
+$(OBJS): $(HDRS)
+
+clean:
+       $(RM) $(PROG) $(OBJS)
+
+help:
+       @echo "make CROSS_COMPILE=arm-linux-gnueabihf- KBUILD_OUTPUT=<Kernel Directory>"
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..5fee7af
--- /dev/null
+++ b/README
@@ -0,0 +1,21 @@
+                       Switch Configuration Utility
+                       ----------------------------
+Introduction
+------------
+Switch-config is user space utility to configure the DM814x, AM387x CPSW 3 Port
+switch with various combination of ALE entry and Phy configuration
+
+how to compile
+--------------
+       make help
+
+Switch configuration commands
+-----------------------------
+For help run the below command
+       switch-config --help
+
+Version
+-------
+For switch-config versions run the below command
+       switch-config --version
+
diff --git a/switch-config.c b/switch-config.c
new file mode 100644 (file)
index 0000000..ce7e388
--- /dev/null
@@ -0,0 +1,665 @@
+/*
+ * Ethernet Switch configuration management
+ *
+ * Copyright (C) 2014 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <stddef.h>
+#include <getopt.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <linux/sockios.h>
+#include <linux/ethtool.h>
+#include <linux/net_switch_config.h>
+
+typedef unsigned long long u64;
+typedef __uint32_t u32;
+typedef __uint16_t u16;
+typedef __uint8_t u8;
+typedef __int32_t s32;
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+#define SWITCH_CONFIG_COMMAND(__var__, __cmd__)                        \
+       if((__var__) == CONFIG_SWITCH_INVALID) {                \
+               (__var__) = (__cmd__);                          \
+       } else {                                                \
+               printf("Two or more commands Cannot be "        \
+                       "processed simultaneously\n");          \
+               return -1;                                      \
+       }
+
+static char options[] = "?m:x:i:y:S:GUg:un:V:sk:K:M:N:D:Y:z:Z:J:v";
+
+static struct option long_options[] =
+       {
+               /* These options set a flag. */
+{"add-multi",                  required_argument       , 0, 'm'},
+{"del-multi",                  required_argument       , 0, 'x'},
+{"add-vlan",                   required_argument       , 0, 'i'},
+{"del-vlan",                   required_argument       , 0, 'y'},
+{"add-unknown-vlan-info",      no_argument             , 0, 'U'},
+{"set-port-config",            required_argument       , 0, 'S'},
+{"get-port-config",            no_argument             , 0, 'G'},
+{"set-port-state",             required_argument       , 0, 'g'},
+{"get-port-state",             no_argument             , 0, 'u'},
+{"port",                       required_argument       , 0, 'n'},
+{"vid",                                required_argument       , 0, 'V'},
+{"super",                      no_argument             , 0, 's'},
+{"fwd-state",                  required_argument       , 0, 'k'},
+{"vid-untag",                  required_argument       , 0, 'K'},
+{"reg-multi",                  required_argument       , 0, 'M'},
+{"unreg-multi",                        required_argument       , 0, 'N'},
+{"vid-untag-port-mask",                required_argument       , 0, 'Y'},
+{"reg-multi-port-mask",                required_argument       , 0, 'z'},
+{"unreg-multi-port-mask",      required_argument       , 0, 'Z'},
+{"unknown-vlan-mem",           required_argument       , 0, 'J'},
+{"duplex",                     required_argument       , 0, 'D'},
+{"version",                    no_argument             , 0, 'v'},
+{0, 0, 0, 0}
+};
+
+static inline int is_zero_ether_addr(const unsigned char *addr)
+{
+       return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]);
+}
+
+static inline int is_multicast_ether_addr(const unsigned char *addr)
+{
+       return 0x01 & addr[0];
+}
+
+static inline int is_valid_ether_addr(const unsigned char *addr)
+{
+       return !is_multicast_ether_addr(addr) && !is_zero_ether_addr(addr);
+}
+
+/* String to Hex conversion */
+static unsigned char cpmac_str_to_hexnum(unsigned char c)
+{
+       if(c >= '0' && c <= '9') return c - '0';
+       if(c >= 'a' && c <= 'f') return c - 'a' + 10;
+       if(c >= 'A' && c <= 'F') return c - 'A' + 10;
+       return 0;
+}
+
+/* String to ethernet address conversion */
+static void config_switch_str_to_ethaddr(char *str, unsigned char *addr)
+{
+       int i;
+       unsigned char num;
+       for(i = 0; i < 6; i++) {
+               if((*str == '.') || (*str == ':')) str++;
+               num = cpmac_str_to_hexnum(*str++) << 4;
+               num |= (cpmac_str_to_hexnum(*str++));
+               addr[i] = num;
+       }
+}
+
+static void
+dump_link_caps(const char *prefix, const char *an_prefix, u32 mask,
+              int link_mode_only)
+{
+       static const struct {
+               int same_line; /* print on same line as previous */
+               u32 value;
+               const char *name;
+       } mode_defs[] = {
+               { 0, ADVERTISED_10baseT_Half,       "10baseT/Half" },
+               { 1, ADVERTISED_10baseT_Full,       "10baseT/Full" },
+               { 0, ADVERTISED_100baseT_Half,      "100baseT/Half" },
+               { 1, ADVERTISED_100baseT_Full,      "100baseT/Full" },
+               { 0, ADVERTISED_1000baseT_Half,     "1000baseT/Half" },
+               { 1, ADVERTISED_1000baseT_Full,     "1000baseT/Full" },
+               { 0, ADVERTISED_1000baseKX_Full,    "1000baseKX/Full" },
+               { 0, ADVERTISED_2500baseX_Full,     "2500baseX/Full" },
+               { 0, ADVERTISED_10000baseT_Full,    "10000baseT/Full" },
+               { 0, ADVERTISED_10000baseKX4_Full,  "10000baseKX4/Full" },
+               { 0, ADVERTISED_10000baseKR_Full,   "10000baseKR/Full" },
+               { 0, ADVERTISED_20000baseMLD2_Full, "20000baseMLD2/Full" },
+               { 0, ADVERTISED_20000baseKR2_Full,  "20000baseKR2/Full" },
+               { 0, ADVERTISED_40000baseKR4_Full,  "40000baseKR4/Full" },
+               { 0, ADVERTISED_40000baseCR4_Full,  "40000baseCR4/Full" },
+               { 0, ADVERTISED_40000baseSR4_Full,  "40000baseSR4/Full" },
+               { 0, ADVERTISED_40000baseLR4_Full,  "40000baseLR4/Full" },
+       };
+       int indent;
+       int did1, new_line_pend, i;
+
+       /* Indent just like the separate functions used to */
+       indent = strlen(prefix) + 14;
+       if (indent < 24)
+               indent = 24;
+
+       fprintf(stdout, "       %s link modes:%*s", prefix,
+               indent - (int)strlen(prefix) - 12, "");
+       did1 = 0;
+       new_line_pend = 0;
+       for (i = 0; i < ARRAY_SIZE(mode_defs); i++) {
+               if (did1 && !mode_defs[i].same_line)
+                       new_line_pend = 1;
+               if (mask & mode_defs[i].value) {
+                       if (new_line_pend) {
+                               fprintf(stdout, "\n");
+                               fprintf(stdout, "       %*s", indent, "");
+                               new_line_pend = 0;
+                       }
+                       did1++;
+                       fprintf(stdout, "%s ", mode_defs[i].name);
+               }
+       }
+       if (did1 == 0)
+                fprintf(stdout, "Not reported");
+       fprintf(stdout, "\n");
+
+       if (!link_mode_only) {
+               fprintf(stdout, "       %s pause frame use: ", prefix);
+               if (mask & ADVERTISED_Pause) {
+                       fprintf(stdout, "Symmetric");
+                       if (mask & ADVERTISED_Asym_Pause)
+                               fprintf(stdout, " Receive-only");
+                       fprintf(stdout, "\n");
+               } else {
+                       if (mask & ADVERTISED_Asym_Pause)
+                               fprintf(stdout, "Transmit-only\n");
+                       else
+                               fprintf(stdout, "No\n");
+               }
+
+               fprintf(stdout, "       %s auto-negotiation: ", an_prefix);
+               if (mask & ADVERTISED_Autoneg)
+                       fprintf(stdout, "Yes\n");
+               else
+                       fprintf(stdout, "No\n");
+       }
+}
+
+static int dump_ecmd(struct ethtool_cmd *ep)
+{
+       u32 speed;
+
+       dump_link_caps("Advertised", "Advertised", ep->advertising, 0);
+       if (ep->lp_advertising)
+               dump_link_caps("Link partner advertised",
+                              "Link partner advertised", ep->lp_advertising,
+                              0);
+
+       fprintf(stdout, "       Speed: ");
+       speed = ethtool_cmd_speed(ep);
+       if (speed == 0 || speed == (u16)(-1) || speed == (u32)(-1))
+               fprintf(stdout, "Unknown!\n");
+       else
+               fprintf(stdout, "%uMb/s\n", speed);
+
+       fprintf(stdout, "       Duplex: ");
+       switch (ep->duplex) {
+       case DUPLEX_HALF:
+               fprintf(stdout, "Half\n");
+               break;
+       case DUPLEX_FULL:
+               fprintf(stdout, "Full\n");
+               break;
+       default:
+               fprintf(stdout, "Unknown! (%i)\n", ep->duplex);
+               break;
+       };
+
+       fprintf(stdout, "       Port: ");
+       switch (ep->port) {
+       case PORT_TP:
+               fprintf(stdout, "Twisted Pair\n");
+               break;
+       case PORT_AUI:
+               fprintf(stdout, "AUI\n");
+               break;
+       case PORT_BNC:
+               fprintf(stdout, "BNC\n");
+               break;
+       case PORT_MII:
+               fprintf(stdout, "MII\n");
+               break;
+       case PORT_FIBRE:
+               fprintf(stdout, "FIBRE\n");
+               break;
+       case PORT_DA:
+               fprintf(stdout, "Direct Attach Copper\n");
+               break;
+       case PORT_NONE:
+               fprintf(stdout, "None\n");
+               break;
+       case PORT_OTHER:
+               fprintf(stdout, "Other\n");
+               break;
+       default:
+               fprintf(stdout, "Unknown! (%i)\n", ep->port);
+               break;
+       };
+
+       fprintf(stdout, "       PHYAD: %d\n", ep->phy_address);
+       fprintf(stdout, "       Transceiver: ");
+       switch (ep->transceiver) {
+       case XCVR_INTERNAL:
+               fprintf(stdout, "internal\n");
+               break;
+       case XCVR_EXTERNAL:
+               fprintf(stdout, "external\n");
+               break;
+       default:
+               fprintf(stdout, "Unknown!\n");
+               break;
+       };
+
+       fprintf(stdout, "       Auto-negotiation: %s\n",
+               (ep->autoneg == AUTONEG_DISABLE) ?
+               "off" : "on");
+
+       if (ep->port == PORT_TP) {
+               fprintf(stdout, "       MDI-X: ");
+               if (ep->eth_tp_mdix_ctrl == ETH_TP_MDI) {
+                       fprintf(stdout, "off (forced)\n");
+               } else if (ep->eth_tp_mdix_ctrl == ETH_TP_MDI_X) {
+                       fprintf(stdout, "on (forced)\n");
+               } else {
+                       switch (ep->eth_tp_mdix) {
+                       case ETH_TP_MDI:
+                               fprintf(stdout, "off");
+                               break;
+                       case ETH_TP_MDI_X:
+                               fprintf(stdout, "on");
+                               break;
+                       default:
+                               fprintf(stdout, "Unknown");
+                               break;
+                       }
+                       if (ep->eth_tp_mdix_ctrl == ETH_TP_MDI_AUTO)
+                               fprintf(stdout, " (auto)");
+                       fprintf(stdout, "\n");
+               }
+       }
+
+       return 0;
+}
+
+void print_help(void)
+{
+       printf(
+               "Switch configuration commands.....\n"
+               "All input and output values are in Decimal\n"
+               "switch-config -m,--add-multi <address> -n,--port <Portmask> "
+                       "[-V,--vid <vid>] [-s,--super] "
+                       "[-k,--fwd-state <value 0-3>]\n"
+               "switch-config -x,--del-multi <address> [-V,--vid <vid>]\n"
+               "switch-config -i,--add-vlan <vlan id> -n,--port <Portmask> "
+                       "[-K,--vid-untag <Portmask>] "
+                       "[-M,--reg-multi <Portmask>] "
+                       "[-N,--unreg-multi <Portmask>]\n"
+               "switch-config -y,--del-vlan <vid>\n"
+               "switch-config -S,--set-port-config <0(auto)/10/100/1000> "
+                       "-n,--port <PortNo> [-D,--duplex <full/half>]\n"
+               "switch-config -G,--get-port-config -n,--port <PortNo>\n"
+               "switch-config -U,--add-unknown-vlan-info "
+                       "[-Y,--vid-untag-port-mask <0-7>] [-z,--reg-multi-port-mask <0-7>] "
+                       "[-Z,--unreg-multi-port-mask <0-7>] "
+                       "[-J,--unknown-vlan-mem <0-7>]\n"
+               "switch-config -g,--get-port-state <disabled/blocked/learn/forward> "
+                       "-n,--port <PortNo>\n"
+               "switch-config -u,--set-port-state -n,--port <PortNo>\n"
+               "\n"
+               );
+}
+
+int main(int argc, char **argv)
+{
+       int option_index = 0;
+       int c;
+       struct net_switch_config cmd_struct;
+       unsigned int port_num = 0;
+       struct ifreq ifr;
+       int sockfd;  /* socket fd we use to manipulate stuff with */
+       unsigned int speed;
+       unsigned int duplex;
+       unsigned int autoneg;
+
+       /* get interface name */
+       strncpy(ifr.ifr_name, "eth0", IFNAMSIZ);
+       ifr.ifr_data = (char*)&cmd_struct;
+       /* Create a channel to the NET kernel. */
+       if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+               printf("Can't open the socket\n");
+               return -1;
+       }
+       memset(&cmd_struct, 0, sizeof(struct net_switch_config));
+
+       /* parse command line arguments */
+       while ((c = getopt_long(argc, argv, options, long_options,
+                       &option_index)) != -1) {
+               switch (c) {
+               case '?':
+                       print_help();
+                       return 0;
+               case 'v':
+                       printf("switch-config version: %s\n", VERSION);
+                       return 0;
+
+               case 'm':
+                       SWITCH_CONFIG_COMMAND(cmd_struct.cmd,
+                               CONFIG_SWITCH_ADD_MULTICAST);
+                       config_switch_str_to_ethaddr(optarg,
+                               cmd_struct.addr);
+               break;
+
+               case 'x':
+                       SWITCH_CONFIG_COMMAND(cmd_struct.cmd,
+                               CONFIG_SWITCH_DEL_MULTICAST);
+                       config_switch_str_to_ethaddr(optarg,
+                               cmd_struct.addr);
+               break;
+
+               case 'i':
+                       SWITCH_CONFIG_COMMAND(cmd_struct.cmd,
+                               CONFIG_SWITCH_ADD_VLAN);
+                       cmd_struct.vid = atoi(optarg);
+               break;
+
+               case 'y':
+                       SWITCH_CONFIG_COMMAND(cmd_struct.cmd,
+                               CONFIG_SWITCH_DEL_VLAN);
+                       cmd_struct.vid = atoi(optarg);
+               break;
+
+               case 'G':
+                       SWITCH_CONFIG_COMMAND(cmd_struct.cmd,
+                               CONFIG_SWITCH_GET_PORT_CONFIG);
+               break;
+
+               case 'S':
+                       SWITCH_CONFIG_COMMAND(cmd_struct.cmd,
+                               CONFIG_SWITCH_SET_PORT_CONFIG);
+                       speed = atoi(optarg);
+                       if (speed == 0)
+                               autoneg = AUTONEG_ENABLE;
+                       else
+                               autoneg = AUTONEG_DISABLE;
+               break;
+
+               case 'U':
+                       SWITCH_CONFIG_COMMAND(cmd_struct.cmd,
+                               CONFIG_SWITCH_ADD_UNKNOWN_VLAN_INFO);
+                       printf("CONFIG_SWITCH_ADD_UNKNOWN_VLAN_INFO\n");
+               break;
+
+               case 'g':
+                       SWITCH_CONFIG_COMMAND(cmd_struct.cmd,
+                               CONFIG_SWITCH_SET_PORT_STATE);
+                       if (!strcmp(optarg, "disabled"))
+                               cmd_struct.port_state = PORT_STATE_DISABLED;
+                       else if (!strcmp(optarg, "blocked"))
+                               cmd_struct.port_state = PORT_STATE_BLOCKED;
+                       else if (!strcmp(optarg, "learn"))
+                               cmd_struct.port_state = PORT_STATE_LEARN;
+                       else if (!strcmp(optarg, "forward"))
+                               cmd_struct.port_state = PORT_STATE_FORWARD;
+                       else {
+                               printf("Invalid Port State\n");
+                               return -1;
+                       }
+               break;
+
+               case 'u':
+                       SWITCH_CONFIG_COMMAND(cmd_struct.cmd,
+                               CONFIG_SWITCH_GET_PORT_STATE);
+               break;
+
+
+/* Command arguments */
+               case 'n':
+                       port_num = atoi(optarg);
+               break;
+
+               case 'V':
+                       cmd_struct.vid = atoi(optarg);
+               break;
+
+               case 'k':
+                       cmd_struct.untag_port = atoi(optarg);
+               break;
+
+               case 'K':
+                       cmd_struct.untag_port = atoi(optarg);
+               break;
+
+               case 'M':
+                       cmd_struct.reg_multi = atoi(optarg);
+               break;
+
+               case 'N':
+                       cmd_struct.unreg_multi = atoi(optarg);
+               break;
+
+               case 'D':
+                       if (!strcmp(optarg, "full"))
+                               duplex = DUPLEX_FULL;
+                       else if (!strcmp(optarg, "half"))
+                               duplex = DUPLEX_HALF;
+                       else {
+                               printf("Invalid Options for Duplex\n");
+                               close(sockfd);
+                               return -1;
+                       }
+               break;
+
+               case 'Y':
+                       cmd_struct.unknown_vlan_untag = atoi(optarg);
+               break;
+
+               case 'z':
+                       cmd_struct.unknown_vlan_reg_multi = atoi(optarg);
+               break;
+
+               case 'Z':
+                       cmd_struct.unknown_vlan_unreg_multi = atoi(optarg);
+               break;
+
+               case 'J':
+                       cmd_struct.unknown_vlan_member = atoi(optarg);
+               break;
+
+               default:
+                       print_help();
+                       return 0;
+               }
+       }
+
+       switch (cmd_struct.cmd) {
+               case CONFIG_SWITCH_INVALID:
+                       print_help();
+                       return -1;
+               break;
+
+               case CONFIG_SWITCH_ADD_MULTICAST:
+                       if ((cmd_struct.vid <= 4095) &&
+                               (port_num > 0) && (port_num <= 7) &&
+                               is_multicast_ether_addr(cmd_struct.addr)) {
+                               cmd_struct.port = port_num;
+                               printf("port number %d\n", cmd_struct.port);
+                               if (ioctl(sockfd, SIOCSWITCHCONFIG, &ifr) < 0) {
+                                       printf("Multicast add failed\n");
+                                       close(sockfd);
+                                       return -1;
+                               } else
+                                       printf("Multicast address added successfully\n");
+                       } else {
+                               printf("Invalid Arguments\n");
+                               return -1;
+                       }
+               break;
+
+               case CONFIG_SWITCH_DEL_MULTICAST:
+                       if ((cmd_struct.vid <= 4095) &&
+                               is_multicast_ether_addr(cmd_struct.addr)) {
+                               if (ioctl(sockfd, SIOCSWITCHCONFIG, &ifr) < 0) {
+                                       printf("Multicast Address Not found\n");
+                                       close(sockfd);
+                                       return -1;
+                               } else
+                                       printf("Multicast Address Deleted successfully\n");
+                       } else {
+                               printf("Invalid Arguments\n");
+                               return -1;
+                       }
+               break;
+
+               case CONFIG_SWITCH_ADD_VLAN:
+                       if ((cmd_struct.vid <= 4095) &&
+                               (port_num > 0) && (port_num <= 7)) {
+                               cmd_struct.port = port_num;
+                               if (ioctl(sockfd, SIOCSWITCHCONFIG, &ifr) < 0) {
+                                       printf("VLAN add failed\n");
+                                       close(sockfd);
+                                       return -1;
+                               } else
+                                       printf("VLAN added successfully\n");
+                       } else {
+                               printf("Invalid Arguments\n");
+                               return -1;
+                       }
+               break;
+
+               case CONFIG_SWITCH_DEL_VLAN:
+                       if ((cmd_struct.vid <= 4095) &&
+                               (port_num <= 7)) {
+                               cmd_struct.port = port_num;
+                               if (ioctl(sockfd, SIOCSWITCHCONFIG, &ifr) < 0) {
+                                       printf("VLAN Not found\n");
+                                       close(sockfd);
+                                       return -1;
+                               } else
+                                       printf("VLAN Deleted Successfully\n");
+                       } else {
+                               printf("Invalid Arguments\n");
+                               return -1;
+                       }
+               break;
+
+               case CONFIG_SWITCH_SET_PORT_CONFIG:
+                       if ((port_num == 1) || (port_num == 2)) {
+                               cmd_struct.port = port_num;
+                               cmd_struct.cmd = CONFIG_SWITCH_GET_PORT_CONFIG;
+
+                               if (ioctl(sockfd, SIOCSWITCHCONFIG, &ifr) < 0) {
+                                       printf("Set Port Config Failed\n");
+                                       close(sockfd);
+                                       return -1;
+                               } else
+                                       printf("Set Port Config successful\n");
+
+                               ethtool_cmd_speed_set(&cmd_struct.ecmd, speed);
+                               cmd_struct.ecmd.duplex = duplex;
+                               cmd_struct.ecmd.autoneg = autoneg;
+                               cmd_struct.cmd = CONFIG_SWITCH_SET_PORT_CONFIG;
+
+                               if (ioctl(sockfd, SIOCSWITCHCONFIG, &ifr) < 0) {
+                                       printf("Set Port Config Failed\n");
+                                       close(sockfd);
+                                       return -1;
+                               } else
+                                       printf("Set Port Config successful\n");
+                       } else {
+                               printf("Invalid Arguments\n");
+                               return -1;
+                       }
+               break;
+
+               case CONFIG_SWITCH_GET_PORT_CONFIG:
+                       if ((port_num == 1) || (port_num == 2)) {
+                               cmd_struct.port = port_num;
+                               if (ioctl(sockfd, SIOCSWITCHCONFIG, &ifr) < 0) {
+                                       printf("Get Port Config Failed\n");
+                                       close(sockfd);
+                                       return -1;
+                               } else {
+                                       printf("Get Port Config successful\n");
+                                       dump_ecmd(&cmd_struct.ecmd);
+                               }
+                       } else {
+                               printf("Invalid Arguments\n");
+                               return -1;
+                       }
+               break;
+
+               case CONFIG_SWITCH_ADD_UNKNOWN_VLAN_INFO:
+                       if ((cmd_struct.unknown_vlan_member <= 7) &&
+                           (cmd_struct.unknown_vlan_untag <= 7) &&
+                           (cmd_struct.unknown_vlan_unreg_multi <= 7) &&
+                           (cmd_struct.unknown_vlan_reg_multi <= 7)) {
+                               if (ioctl(sockfd, SIOCSWITCHCONFIG, &ifr) < 0) {
+                                       printf("Add unknown VLAN Failed\n");
+                                       close(sockfd);
+                                       return -1;
+                               } else {
+                                       printf("Add unknown VLAN successful\n");
+                               }
+                       } else {
+                               printf("Invalid Arguments\n");
+                               return -1;
+                       }
+               break;
+
+               case CONFIG_SWITCH_SET_PORT_STATE:
+                       if ((port_num == 1) || (port_num == 2)) {
+                               cmd_struct.port = port_num;
+                               if (ioctl(sockfd, SIOCSWITCHCONFIG, &ifr) < 0) {
+                                       printf("Set Port State Failed\n");
+                                       close(sockfd);
+                                       return -1;
+                               } else
+                                       printf("Set Port State successful\n");
+                       } else {
+                               printf("Invalid Arguments\n");
+                               return -1;
+                       }
+               break;
+
+               case CONFIG_SWITCH_GET_PORT_STATE:
+                       if ((port_num == 1) || (port_num == 2)) {
+                               cmd_struct.port = port_num;
+                               if (ioctl(sockfd, SIOCSWITCHCONFIG, &ifr) < 0) {
+                                       printf("Get Port State Failed\n");
+                                       close(sockfd);
+                                       return -1;
+                               } else
+                                       printf("Get Port State successful\nState is ");
+                               if (cmd_struct.port_state == PORT_STATE_DISABLED)
+                                       printf("disabled\n");
+                               else if (cmd_struct.port_state == PORT_STATE_BLOCKED)
+                                       printf("blocked\n");
+                               else if (cmd_struct.port_state == PORT_STATE_LEARN)
+                                       printf("learn\n");
+                               else if (cmd_struct.port_state == PORT_STATE_FORWARD)
+                                       printf("forward\n");
+                               else
+                                       printf("Invalid State\n");
+                       } else {
+                               printf("Invalid Arguments\n");
+                               return -1;
+                       }
+               break;
+       }
+
+       close(sockfd);
+       return 0;
+}