/* ========================================================================= * The Synopsys DWC ETHER QOS Software Driver and documentation (hereinafter * "Software") is an unsupported proprietary work of Synopsys, Inc. unless * otherwise expressly agreed to in writing between Synopsys and you. * * The Software IS NOT an item of Licensed Software or Licensed Product under * any End User Software License Agreement or Agreement for Licensed Product * with Synopsys or any supplement thereto. Permission is hereby granted, * free of charge, to any person obtaining a copy of this software annotated * with this license and the Software, to deal in the Software without * restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, subject * to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * ========================================================================= */ #include #include #include #include /* for socket programming */ #include #include #include #include #include /* for struct ifreq */ #include /* for IOCTL no */ #include #include "DWC_ETH_QOS_yapphdr.h" static unsigned int tx_queue_count = 1; static unsigned int rx_queue_count = 1; static unsigned int connected_speed = SPEED_100; static char *exe_name; static char *if_name; static int print_all; static int open_socket(char *ifname) { int sockfd; sockfd = socket(PF_INET, SOCK_STREAM, 0); return sockfd; } static void close_socket(int sockfd) { close(sockfd); } unsigned int wakeup_filter_config[] = { /* for filter 0 CRC is computed on 0 - 7 bytes from offset */ 0x000000ff, /* for filter 1 CRC is computed on 0 - 7 bytes from offset */ 0x000000ff, /* for filter 2 CRC is computed on 0 - 7 bytes from offset */ 0x000000ff, /* for filter 3 CRC is computed on 0 - 31 bytes from offset */ 0x000000ff, /* filter 0, 1 independently enabled and would apply for * unicast packet only filter 3, 2 combined as, * "Filter-3 pattern AND NOT Filter-2 pattern" */ 0x03050101, /* filter 3, 2, 1 and 0 offset is 50, 58, 66, 74 bytes * from start */ 0x4a423a32, /* pattern for filter 1 and 0, "0x55", "11", repeated 8 times */ 0xe7b77eed, /* pattern for filter 3 and 4, "0x44", "33", repeated 8 times */ 0x9b8a5506, }; int populate_filter_frames(struct ifr_data_struct *data) { int i; for (i = 0; i < DWC_ETH_QOS_RWK_FILTER_LENGTH; i++) data->rwk_filter_values[i] = wakeup_filter_config[i]; data->rwk_filter_length = DWC_ETH_QOS_RWK_FILTER_LENGTH; return 0; } static int DWC_ETH_QOS_get_rx_qcnt(int sockfd, char *ifname) { struct ifreq ifr; struct ifr_data_struct data; int ret = 0; data.cmd = DWC_ETH_QOS_GET_RX_QCNT; data.qInx = 0; strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) printf("IOCTL Error\n"); else printf("Rx queue count is %d\n", data.qInx); return data.qInx; } static int DWC_ETH_QOS_get_tx_qcnt(int sockfd, char *ifname) { struct ifreq ifr; struct ifr_data_struct data; int ret = 0; data.cmd = DWC_ETH_QOS_GET_TX_QCNT; data.qInx = 0; strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) printf("IOCTL Error\n"); else printf("Tx queue count is %d\n", data.qInx); return data.qInx; } static int DWC_ETH_QOS_get_connected_speed(int sockfd, char *ifname) { struct ifreq ifr; struct ifr_data_struct data; int ret = 0; data.cmd = DWC_ETH_QOS_GET_CONNECTED_SPEED; data.qInx = 0; strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) printf("IOCTL Error\n"); else printf("Connected speed is %dMBps\n", data.connected_speed); return data.connected_speed; } static unsigned int DWC_ETH_QOS_get_dcb_queue_weights(unsigned int dcb_algorithm, unsigned int percent_weight, unsigned int max_frame_size) { unsigned int weight = 0; switch (dcb_algorithm) { case eDWC_ETH_QOS_DCB_WRR: weight = percent_weight; break; case eDWC_ETH_QOS_DCB_DWRR: weight = (percent_weight * max_frame_size); break; case eDWC_ETH_QOS_DCB_WFQ: weight = (DWC_ETH_QOS_MAX_WFQ_WEIGHT/(percent_weight+1)); break; case eDWC_ETH_QOS_DCB_SP: /* queue weights are ignored with this algorithm */ break; } return weight; } static unsigned int get_idle_slope(unsigned char bw) { unsigned int multiplier = 1; unsigned int idle_slope = 0; if (connected_speed == SPEED_1000) multiplier = 2; /* * idleslope = ((bandwidth/100) * (4 [for MII] or 8 [for GMII])) * 1024 * 1024 is multiplied for normalizing the calculated value */ idle_slope = (((4 * multiplier * bw) * 1024)/100); return idle_slope; } static unsigned int get_send_slope(unsigned char bw) { unsigned int multiplier = 1; unsigned int idle_slope = 0; unsigned int send_slope = 0; if (connected_speed == SPEED_1000) multiplier = 2; /* * sendslope = (((100 - bandwidth)/100) * (4 [for MII] or 8 [for GMII])) * 1024 * 1024 is multiplied for normalizing the calculated value * OR * sendslope = (1024 * (4 [for MII] or 8 [for GMII]) - idle_slope) */ //send_slope = (((4 * multiplier * (100 - bw)) * 1024)/100); idle_slope = (((4 * multiplier * bw) * 1024)/100); send_slope = ((4 * multiplier * 1024)- idle_slope); return send_slope; } static unsigned int get_hi_credit(unsigned char bw) { unsigned int hi_credit = 0; hi_credit = (uint64_t)(((uint64_t)DWC_ETH_QOS_MAX_INT_FRAME_SIZE * (uint64_t)bw * 1024 * 8))/100; return hi_credit; } static unsigned int get_low_credit(unsigned char bw) { unsigned int hi_credit = 0; int low_credit = 0; hi_credit = (uint64_t)(((uint64_t)DWC_ETH_QOS_MAX_INT_FRAME_SIZE * (uint64_t)bw * 1024 * 8))/100; low_credit = -((uint64_t)(((uint64_t)DWC_ETH_QOS_MAX_INT_FRAME_SIZE * (100 - bw)) * 1024 * 8)/100); return low_credit; } static int powerup_device(int sockfd, char *ifname, char *parameter) { struct ifreq ifr; struct ifr_data_struct data; int ret = 0; if (strcmp("magic", parameter) == 0) data.cmd = DWC_ETH_QOS_POWERUP_MAGIC_CMD; else if (strcmp("remote_wakeup", parameter) == 0) data.cmd = DWC_ETH_QOS_POWERUP_REMOTE_WAKEUP_CMD; strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; data.qInx = 0; /* Not used */ ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) { printf("IOCTL Error\n"); switch (data.command_error) { case DWC_ETH_QOS_NO_HW_SUPPORT: printf("No hardware support present for %s\n", parameter); break; case DWC_ETH_QOS_CONFIG_FAIL: printf("Powerup already done\n"); break; } } else printf("Got the device out of power down mode for '%s'\n", parameter); return ret; } static int powerdown_device(int sockfd, char *ifname, char *parameter) { struct ifreq ifr; struct ifr_data_struct data; int ret = 0; char *str = NULL; if (strcmp("magic", parameter) == 0) { str = "magic"; data.cmd = DWC_ETH_QOS_POWERDOWN_MAGIC_CMD; } else if (strcmp("remote_wakeup", parameter) == 0) { str = "remote wakeup"; data.cmd = DWC_ETH_QOS_POWERDOWN_REMOTE_WAKEUP_CMD; populate_filter_frames(&data); } strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; data.qInx = 0; /* Not used */ ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) { printf("IOCTL Error\n"); switch (data.command_error) { case DWC_ETH_QOS_NO_HW_SUPPORT: printf("No hardware support present for %s\n", str); break; case DWC_ETH_QOS_CONFIG_FAIL: printf("Powerdown already done\n"); break; } } else { printf("Put the device in power down mode\n"); printf("Device will now power up on manual 'powerup' with"\ " '%s' or on receiving a %s packet\n", parameter, str); } return ret; } static int config_rx_threshold(int sockfd, char *ifname, char *argv1, char *argv2) { struct ifreq ifr; struct ifr_data_struct data; unsigned int qInx = atoi(argv1); int option = atoi(argv2); int ret = 0; if ((qInx > DWC_ETH_QOS_MAX_RX_QUEUE_CNT) || (qInx < 0)) { printf("Invalid channel no %d\n", qInx); return -1; } switch (option) { case 32: data.flags = DWC_ETH_QOS_RX_THRESHOLD_32; break; case 64: data.flags = DWC_ETH_QOS_RX_THRESHOLD_64; break; case 96: data.flags = DWC_ETH_QOS_RX_THRESHOLD_96; break; case 128: data.flags = DWC_ETH_QOS_RX_THRESHOLD_128; break; default: printf("Invalid option %d\n", option); return -1; } data.cmd = DWC_ETH_QOS_RX_THRESHOLD_CMD; data.qInx = qInx; strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) printf("IOCTL Error\n"); else printf("Successfully configured RX threshold to %d bytes\n", option); return ret; } static int config_tx_threshold(int sockfd, char *ifname, char *argv1, char *argv2) { struct ifreq ifr; struct ifr_data_struct data; unsigned int qInx = atoi(argv1); int option = atoi(argv2); int ret = 0; if ((qInx > DWC_ETH_QOS_MAX_TX_QUEUE_CNT) || (qInx < 0)) { printf("Invalid channel no %d\n", qInx); return -1; } switch (option) { case 32: data.flags = DWC_ETH_QOS_TX_THRESHOLD_32; break; case 64: data.flags = DWC_ETH_QOS_TX_THRESHOLD_64; break; case 96: data.flags = DWC_ETH_QOS_TX_THRESHOLD_96; break; case 128: data.flags = DWC_ETH_QOS_TX_THRESHOLD_128; break; case 192: data.flags = DWC_ETH_QOS_TX_THRESHOLD_192; break; case 256: data.flags = DWC_ETH_QOS_TX_THRESHOLD_256; break; case 384: data.flags = DWC_ETH_QOS_TX_THRESHOLD_384; break; case 512: data.flags = DWC_ETH_QOS_TX_THRESHOLD_512; break; default: printf("Invalid option %d\n", option); return -1; } data.cmd = DWC_ETH_QOS_TX_THRESHOLD_CMD; data.qInx = qInx; strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) printf("IOCTL Error\n"); else printf("Successfully configured TX threshold to %d bytes\n", option); return ret; } static int config_rsf(int sockfd, char *ifname, char *argv1, char *argv2) { struct ifreq ifr; struct ifr_data_struct data; unsigned int qInx = atoi(argv1); int option = atoi(argv2); int ret = 0; if ((qInx > DWC_ETH_QOS_MAX_RX_QUEUE_CNT) || (qInx < 0)) { printf("Invalid channel no %d\n", qInx); return -1; } switch (option) { case 0: data.flags = DWC_ETH_QOS_RSF_DISABLE; break; case 1: data.flags = DWC_ETH_QOS_RSF_ENABLE; break; default: printf("Invalid option %d\n", option); return -1; } data.cmd = DWC_ETH_QOS_RSF_CMD; data.qInx = qInx; strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) printf("IOCTL Error\n"); else printf("Successfully %s Receive Store and Forward Mode\n", (option ? "ENABLED" : "DISABLED")); return ret; } static int config_tsf(int sockfd, char *ifname, char *argv1, char *argv2) { struct ifreq ifr; struct ifr_data_struct data; unsigned int qInx = atoi(argv1); int option = atoi(argv2); int ret = 0; if ((qInx > DWC_ETH_QOS_MAX_TX_QUEUE_CNT) || (qInx < 0)) { printf("Invalid channel no %d\n", qInx); return -1; } switch (option) { case 0: data.flags = DWC_ETH_QOS_TSF_DISABLE; break; case 1: data.flags = DWC_ETH_QOS_TSF_ENABLE; break; default: printf("Invalid option %d\n", option); return -1; } data.cmd = DWC_ETH_QOS_TSF_CMD; data.qInx = qInx; strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) printf("IOCTL Error\n"); else printf("Successfully %s Transmit Store and Forward Mode\n", (option ? "ENABLED" : "DISABLED")); return ret; } static int config_osf(int sockfd, char *ifname, char *argv1, char *argv2) { struct ifreq ifr; struct ifr_data_struct data; unsigned int qInx = atoi(argv1); int option = atoi(argv2); int ret = 0; if ((qInx > DWC_ETH_QOS_MAX_TX_QUEUE_CNT) || (qInx < 0)) { printf("Invalid channel no %d\n", qInx); return -1; } switch (option) { case 0: data.flags = DWC_ETH_QOS_OSF_DISABLE; break; case 1: data.flags = DWC_ETH_QOS_OSF_ENABLE; break; default: printf("Invalid option %d\n", option); return -1; } data.cmd = DWC_ETH_QOS_OSF_CMD; data.qInx = qInx; strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) printf("IOCTL Error\n"); else printf ("Successfully %s Transmit Operate on Second Frame Mode\n", (option ? "ENABLED" : "DISABLED")); return ret; } static int config_incrx_incr(int sockfd, char *ifname, char *argv) { struct ifreq ifr; struct ifr_data_struct data; int option = atoi(argv); int ret = 0; switch (option) { case 0: data.flags = DWC_ETH_QOS_INCRX_ENABLE; break; case 1: data.flags = DWC_ETH_QOS_INCR_ENABLE; break; default: printf("Invalid option %d\n", option); return -1; } data.cmd = DWC_ETH_QOS_INCR_INCRX_CMD; data.qInx = 0; /* Not used */ strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) printf("IOCTL Error\n"); else printf("Successfully configured device in %s mode\n", option ? "INCRX" : "INCR"); return ret; } static int config_rx_pbl(int sockfd, char *ifname, char *argv1, char *argv2) { struct ifreq ifr; struct ifr_data_struct data; unsigned int qInx = atoi(argv1); int option = atoi(argv2); int ret = 0; if ((qInx > DWC_ETH_QOS_MAX_RX_QUEUE_CNT) || (qInx < 0)) { printf("Invalid channel no %d\n", qInx); return -1; } switch (option) { case DWC_ETH_QOS_PBL_1: case DWC_ETH_QOS_PBL_2: case DWC_ETH_QOS_PBL_4: case DWC_ETH_QOS_PBL_8: case DWC_ETH_QOS_PBL_16: case DWC_ETH_QOS_PBL_32: case DWC_ETH_QOS_PBL_64: case DWC_ETH_QOS_PBL_128: case DWC_ETH_QOS_PBL_256: data.flags = option; break; default: printf("Invalid option %d\n", option); return -1; } data.cmd = DWC_ETH_QOS_RX_PBL_CMD; data.qInx = qInx; strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) printf("IOCTL Error\n"); else printf("Successfully configured RX PBL to %d\n", option); return ret; } static int config_tx_pbl(int sockfd, char *ifname, char *argv1, char *argv2) { struct ifreq ifr; struct ifr_data_struct data; unsigned int qInx = atoi(argv1); int option = atoi(argv2); int ret = 0; if ((qInx > DWC_ETH_QOS_MAX_TX_QUEUE_CNT) || (qInx < 0)) { printf("Invalid channel no %d\n", qInx); return -1; } switch (option) { case DWC_ETH_QOS_PBL_1: case DWC_ETH_QOS_PBL_2: case DWC_ETH_QOS_PBL_4: case DWC_ETH_QOS_PBL_8: case DWC_ETH_QOS_PBL_16: case DWC_ETH_QOS_PBL_32: case DWC_ETH_QOS_PBL_64: case DWC_ETH_QOS_PBL_128: case DWC_ETH_QOS_PBL_256: data.flags = option; break; default: printf("Invalid option %d\n", option); return -1; } data.cmd = DWC_ETH_QOS_TX_PBL_CMD; data.qInx = qInx; strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) printf("IOCTL Error\n"); else printf("Successfully configured TX PBL to %d\n", option); return ret; } /* return 0 on success and -ve on failure */ #if 0 static int rx_outer_vlan_strip(int sockfd, char *ifname, char *argv1) { struct ifreq ifr; struct ifr_data_struct data; int option = atoi(argv1); int ret = 0; char *string = NULL; switch (option) { case 0: data.flags = DWC_ETH_QOS_RX_NO_VLAN_STRIP; string = "not to strip outer RX VLAN Tag"; break; case 1: data.flags = DWC_ETH_QOS_RX_VLAN_STRIP_IF_FILTER_PASS; string = "strip outer RX VLAN Tag if it passes VLAN filter"; break; case 2: data.flags = DWC_ETH_QOS_RX_VLAN_STRIP_IF_FILTER_FAIL; string = "strip outer RX VLAN Tag if it fail VLAN filter"; break; case 3: data.flags = DWC_ETH_QOS_RX_VLAN_STRIP_ALWAYS; string = "strip outer RX VLAN Tag always"; break; default: printf("Invalid option %d\n", option); return -1; } data.cmd = DWC_ETH_QOS_RX_OUTER_VLAN_STRIPPING_CMD; data.qInx = 0; /* Not used */ strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) printf("IOCTL Error\n"); else printf("Successfully configured device to %s\n", string); return ret; } /* return 0 on success and -ve on failure */ static int rx_inner_vlan_strip(int sockfd, char *ifname, char *argv1) { struct ifreq ifr; struct ifr_data_struct data; int option = atoi(argv1); int ret = 0; char *string = NULL; switch (option) { case 0: data.flags = DWC_ETH_QOS_RX_NO_VLAN_STRIP; string = "not to strip inner RX VLAN Tag"; break; case 1: data.flags = DWC_ETH_QOS_RX_VLAN_STRIP_IF_FILTER_PASS; string = "strip inner RX VLAN Tag if it passes VLAN filter"; break; case 2: data.flags = DWC_ETH_QOS_RX_VLAN_STRIP_IF_FILTER_FAIL; string = "strip inner RX VLAN Tag if it fail VLAN filter"; break; case 3: data.flags = DWC_ETH_QOS_RX_VLAN_STRIP_ALWAYS; string = "strip inner RX VLAN Tag always"; break; default: printf("Invalid option %d\n", option); return -1; } data.cmd = DWC_ETH_QOS_RX_INNER_VLAN_STRIPPING_CMD; data.qInx = 0; /* Not used */ strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) printf("IOCTL Error\n"); else printf("Successfully configured device to %s\n", string); return ret; } /* return 0 on success and -ve on failure */ static int tx_vlan_ctrl_via_desc(int sockfd, char *ifname, char *argv1, char *argv2) { struct ifreq ifr; struct ifr_data_struct data; int qInx = atoi(argv1); int option = atoi(argv2); int ret = 0; char *string = NULL; switch (option) { case 0: data.flags = DWC_ETH_QOS_TX_VLAN_TAG_NONE; string = "not TX VLAN Tag deletion, insertion or replacement"; break; case 1: data.flags = DWC_ETH_QOS_TX_VLAN_TAG_DELETE; string = "TX VLAN Tag deletion"; break; case 2: data.flags = DWC_ETH_QOS_TX_VLAN_TAG_INSERT; string = "TX VLAN Tag insertion"; break; case 3: data.flags = DWC_ETH_QOS_TX_VLAN_TAG_REPLACE; string = "TX VLAN Tag replacement"; break; default: printf("Invalid option %d\n", option); return -1; } data.cmd = DWC_ETH_QOS_TX_VLAN_DESC_CMD; data.qInx = qInx; strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) printf("IOCTL Error\n"); else printf("Successfully configured device to"\ " (per packet based) %s\n", string); return ret; } /* return 0 on success and -ve on failure */ static int tx_vlan_ctrl_via_reg(int sockfd, char *ifname, char *argv1, char *argv2) { struct ifreq ifr; struct ifr_data_struct data; int qInx = atoi(argv1); int option = atoi(argv2); int ret = 0; char *string = NULL; switch (option) { case 0: data.flags = DWC_ETH_QOS_TX_VLAN_TAG_NONE; string = "not TX VLAN Tag deletion, insertion or replacement"; break; case 1: data.flags = DWC_ETH_QOS_TX_VLAN_TAG_DELETE; string = "TX VLAN Tag deletion"; break; case 2: data.flags = DWC_ETH_QOS_TX_VLAN_TAG_INSERT; string = "TX VLAN Tag insertion"; break; case 3: data.flags = DWC_ETH_QOS_TX_VLAN_TAG_REPLACE; string = "TX VLAN Tag replacement"; break; default: printf("Invalid option %d\n", option); return -1; } data.cmd = DWC_ETH_QOS_TX_VLAN_REG_CMD; data.qInx = qInx; strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) printf("IOCTL Error\n"); else printf ("Successfully configured device to (register based) %s\n", string); return ret; } #endif /* return 0 on success and -ve on failure */ static int sa0_ctrl_via_desc(int sockfd, char *ifname, char *argv) { struct ifreq ifr; struct ifr_data_struct data; int option = atoi(argv); int ret = 0; char *string = NULL; switch (option) { case 0: data.flags = DWC_ETH_QOS_SA0_NONE; string = "Do not include the source address with value given"\ " in the MAC Address 0 reg"; break; case 1: data.flags = DWC_ETH_QOS_SA0_DESC_INSERT; string = "Include/Insert the source address with the value"\ " given in the MAC Address 0 reg"; break; case 2: data.flags = DWC_ETH_QOS_SA0_DESC_REPLACE; string = "Replace the source address with the value given in"\ " the MAC Address 0 reg"; break; default: printf("Invalid option %d\n", option); return -1; } data.cmd = DWC_ETH_QOS_SA0_DESC_CMD; data.qInx = 0; /* Not used */ strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) printf("IOCTL Error\n"); else printf("Successfully configured device to"\ " (per packet based) %s\n", string); return ret; } static int sa1_ctrl_via_desc(int sockfd, char *ifname, char *argv) { struct ifreq ifr; struct ifr_data_struct data; int option = atoi(argv); int ret = 0; char *string = NULL; switch (option) { case 0: data.flags = DWC_ETH_QOS_SA1_NONE; string = "Do not include the source address with value given"\ " in the MAC Address 1 reg"; break; case 1: data.flags = DWC_ETH_QOS_SA1_DESC_INSERT; string = "Include/Insert the source address with value given"\ " in the MAC Address 1 reg"; break; case 2: data.flags = DWC_ETH_QOS_SA1_DESC_REPLACE; string = "Replace the source address with value given in the"\ " MAC Address 1 reg"; break; default: printf("Invalid option %d\n", option); return -1; } data.cmd = DWC_ETH_QOS_SA1_DESC_CMD; data.qInx = 0; /* Not used */ strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) printf("IOCTL Error\n"); else printf("Successfully configured device to"\ " (per packet based) %s\n", string); return ret; } /* return 0 on success and -ve on failure */ static int sa0_ctrl_via_reg(int sockfd, char *ifname, char *argv) { struct ifreq ifr; struct ifr_data_struct data; int option = atoi(argv); int ret = 0; char *string = NULL; switch (option) { case 0: data.flags = DWC_ETH_QOS_SA0_NONE; string = "Do not include the source address with value given"\ " in the MAC Address 0 reg"; break; case 1: data.flags = DWC_ETH_QOS_SA0_REG_INSERT; string = "Include/Insert the source address with the value"\ " given in the MAC Address 0 reg"; break; case 2: data.flags = DWC_ETH_QOS_SA0_REG_REPLACE; string = "Replace the source address with the value given in"\ " the MAC Address 0 reg"; break; default: printf("Invalid option %d\n", option); return -1; } data.cmd = DWC_ETH_QOS_SA0_REG_CMD; data.qInx = 0; /* Not used */ strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) printf("IOCTL Error\n"); else printf ("Successfully configured device to (register based) %s\n", string); return ret; } static int sa1_ctrl_via_reg(int sockfd, char *ifname, char *argv) { struct ifreq ifr; struct ifr_data_struct data; int option = atoi(argv); int ret = 0; char *string = NULL; switch (option) { case 0: data.flags = DWC_ETH_QOS_SA1_NONE; string = "Do not include the source address with value given"\ " in the MAC Address 1 reg"; break; case 1: data.flags = DWC_ETH_QOS_SA1_REG_INSERT; string = "Include/Insert the source address with value given"\ " in the MAC Address 1 reg"; break; case 2: data.flags = DWC_ETH_QOS_SA1_REG_REPLACE; string = "Replace the source address with value given in the"\ " MAC Address 1 reg"; break; default: printf("Invalid option %d\n", option); return -1; } data.cmd = DWC_ETH_QOS_SA1_REG_CMD; data.qInx = 0; /* Not used */ strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) printf("IOCTL Error\n"); else printf ("Successfully configured device to (register based) %s\n", string); return ret; } static int program_dcb_algorithm(int sockfd, char *ifname, char *argv1, char *argv2, char *argv3, char *argv4) { struct ifreq ifr; struct ifr_data_struct data; struct DWC_ETH_QOS_dcb_algorithm dcb_struct; int qInx = atoi(argv1); int algo = atoi(argv2); int percent_weight = atoi(argv3); int max_frame_size = atoi(argv4); int ret = 0; data.cmd = DWC_ETH_QOS_DCB_ALGORITHM; data.qInx = qInx; dcb_struct.qInx = qInx; dcb_struct.algorithm = algo; dcb_struct.weight = DWC_ETH_QOS_get_dcb_queue_weights(algo, percent_weight, max_frame_size); dcb_struct.op_mode = eDWC_ETH_QOS_QDCB; data.ptr = &dcb_struct; strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) printf("IOCTL Error\n"); else printf("Configured DCB Algorithm parameters successfully\n"); return ret; } static int program_avb_algorithm(int sockfd, char *ifname, char *argv1, char *argv2, char *argv3, char *argv4) { struct ifreq ifr; struct ifr_data_struct data; struct DWC_ETH_QOS_avb_algorithm avb_struct; int qInx = atoi(argv1); int algo = atoi(argv2); int bw = atoi(argv3); int cc = atoi(argv4); int ret = 0; data.cmd = DWC_ETH_QOS_AVB_ALGORITHM; data.qInx = qInx; avb_struct.qInx = qInx; avb_struct.algorithm = algo; avb_struct.cc = cc; avb_struct.idle_slope = get_idle_slope(bw); avb_struct.send_slope = get_send_slope(bw); avb_struct.hi_credit = get_hi_credit(bw); avb_struct.low_credit = get_low_credit(bw); avb_struct.op_mode = eDWC_ETH_QOS_QAVB; data.ptr = &avb_struct; strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) printf("IOCTL Error\n"); else printf("Configured AVB Algorithm parameters successfully\n"); return ret; } static int setup_context_descriptor(int sockfd, char *ifname, char *argv1, char *argv2) { struct ifreq ifr; struct ifr_data_struct data; int qInx = atoi(argv1); int setup = atoi(argv2); int ret = 0; data.cmd = DWC_ETH_QOS_SETUP_CONTEXT_DESCRIPTOR; data.context_setup = setup; data.qInx = qInx; strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) printf("IOCTL Error\n"); else printf("Context descriptor configuration changed\n"); return ret; } static int config_rx_split_hdr(int sockfd, char *ifname, char *argv1) { struct ifreq ifr; struct ifr_data_struct data; int option = atoi(argv1); int ret = 0; if (option) data.flags = DWC_ETH_QOS_RX_SPLIT_HDR_ENABLE; else data.flags = DWC_ETH_QOS_RX_SPLIT_HDR_DISABLE; data.cmd = DWC_ETH_QOS_RX_SPLIT_HDR_CMD; data.qInx = 0; /* Not used */ strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) { printf("IOCTL Error\n"); switch (data.command_error) { case DWC_ETH_QOS_NO_HW_SUPPORT: printf("No hardware support present for Split header\n"); break; case DWC_ETH_QOS_CONFIG_FAIL: printf("Rx Split header mode is already %s\n", (option ? "enabled" : "disable")); break; } } else printf("Successfully %s Rx Split header mode\n", (option ? "enabled" : "disabled")); return ret; } static int config_l3_l4_filter(int sockfd, char *ifname, char *enable_disable) { struct ifreq ifr; struct ifr_data_struct data; int option = atoi(enable_disable); int ret = 0; if (option) data.flags = DWC_ETH_QOS_L3_L4_FILTER_ENABLE; else data.flags = DWC_ETH_QOS_L3_L4_FILTER_DISABLE; data.cmd = DWC_ETH_QOS_L3_L4_FILTER_CMD; data.qInx = 0; /* Not used */ strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) { printf("IOCTL Error\n"); switch (data.command_error) { case DWC_ETH_QOS_NO_HW_SUPPORT: printf("No hardware support present for L3/L4 filtering\n"); break; case DWC_ETH_QOS_CONFIG_FAIL: printf("L3/L4 filtering is already %s\n", (option ? "ENABLED" : "DISABLED")); break; } } else printf("Successfully %s L3/L4 filtering\n", (option ? "ENABLED" : "DISABLED")); return ret; } static int check_for_valid_ipv4_addr(char *ip) { int i = 0, ret = 0; char *token = NULL; token = strtok(ip, "."); if (token) { while(1) { token = strtok(NULL, "."); if (!token) { break; } i++; } } if (i != 3) ret = -1; return ret; } static int check_for_valid_ipv6_addr(char *ip) { int i = 0, ret = 0; char *token = NULL; token = strtok(ip, ":"); if (token) { while(1) { token = strtok(NULL, ":"); if (!token) { break; } i++; } } if (i != 7) ret = -1; return ret; } static int config_ipv4_filters(int sockfd, char *ifname, char *filter_no, char *src_dst_addr_match, char *enable_disable, char *perfect_inverse_match, char *ip) { struct ifreq ifr; struct ifr_data_struct data; struct DWC_ETH_QOS_l3_l4_filter l3_filter; char *tmp; int ret = 0; data.flags = atoi(enable_disable); data.cmd = DWC_ETH_QOS_IPV4_FILTERING_CMD; data.qInx = 0; /* Not used */ strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; l3_filter.filter_no = atoi(filter_no); if (l3_filter.filter_no < 0 || l3_filter.filter_no > 7) { printf("Filter number should be between 0 to 7\n"); return -1; } l3_filter.src_dst_addr_match = atoi(src_dst_addr_match); l3_filter.filter_enb_dis = atoi(enable_disable); if (l3_filter.filter_enb_dis) { l3_filter.perfect_inverse_match = atoi(perfect_inverse_match); if (!strcmp(ip, "0")) { memset(l3_filter.ip4_addr, 0, sizeof(l3_filter.ip4_addr)); } else { tmp = strdup(ip); ret = check_for_valid_ipv4_addr(tmp); if (!ret) { l3_filter.ip4_addr[0] = strtol(strtok(ip, "."), NULL, 10); l3_filter.ip4_addr[1] = strtol(strtok(NULL, "."), NULL, 10); l3_filter.ip4_addr[2] = strtol(strtok(NULL, "."), NULL, 10); l3_filter.ip4_addr[3] = strtol(strtok(NULL, "."), NULL, 10); } else { printf("ERROR: Specify correct IPv4 addr(eq - 10.144.134.108)\n"); return ret; } } } else { l3_filter.perfect_inverse_match = 0; memset(l3_filter.ip4_addr, 0, sizeof(l3_filter.ip4_addr)); } data.ptr = &l3_filter; printf("%d.%d.%d.%d\n", l3_filter.ip4_addr[0], l3_filter.ip4_addr[1], l3_filter.ip4_addr[2], l3_filter.ip4_addr[3]); ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) { printf("IOCTL Error\n"); switch (data.command_error) { case DWC_ETH_QOS_NO_HW_SUPPORT: printf("No hardware support present for IPv4 addr filtering\n"); break; default: printf("IPv4(L3) filtering is failed\n"); break; } } else printf("Successfully %s IPv4 %s %s addressing filtering on %d filter\n", (l3_filter.filter_enb_dis ? "ENABLED" : "DISABLED"), (l3_filter.perfect_inverse_match ? "INVERSE" : "PERFECT"), (l3_filter.src_dst_addr_match ? "DESTINATION" : "SOURCE"), l3_filter.filter_no); return ret; } static int config_ipv6_filters(int sockfd, char *ifname, char *filter_no, char *src_dst_addr_match, char *enable_disable, char *perfect_inverse_match, char *ip) { struct ifreq ifr; struct ifr_data_struct data; struct DWC_ETH_QOS_l3_l4_filter l3_filter; char *tmp; int ret = 0; data.flags = atoi(enable_disable); data.cmd = DWC_ETH_QOS_IPV6_FILTERING_CMD; data.qInx = 0; /* Not used */ strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; l3_filter.filter_no = atoi(filter_no); if (l3_filter.filter_no < 0 || l3_filter.filter_no > 7) { printf("Filter number should be between 0 to 7\n"); return -1; } l3_filter.src_dst_addr_match = atoi(src_dst_addr_match); l3_filter.filter_enb_dis = atoi(enable_disable); if (l3_filter.filter_enb_dis) { l3_filter.perfect_inverse_match = atoi(perfect_inverse_match); if (!strcmp(ip, "0")) { memset(l3_filter.ip6_addr, 0, sizeof(l3_filter.ip6_addr)); } else { tmp = strdup(ip); ret = check_for_valid_ipv6_addr(tmp); if (!ret) { l3_filter.ip6_addr[0] = strtol(strtok(ip, ":"), NULL, 16); l3_filter.ip6_addr[1] = strtol(strtok(NULL, ":"), NULL, 16); l3_filter.ip6_addr[2] = strtol(strtok(NULL, ":"), NULL, 16); l3_filter.ip6_addr[3] = strtol(strtok(NULL, ":"), NULL, 16); l3_filter.ip6_addr[4] = strtol(strtok(NULL, ":"), NULL, 16); l3_filter.ip6_addr[5] = strtol(strtok(NULL, ":"), NULL, 16); l3_filter.ip6_addr[6] = strtol(strtok(NULL, ":"), NULL, 16); l3_filter.ip6_addr[7] = strtol(strtok(NULL, ":"), NULL, 16); } else { printf("ERROR: Specify correct IPv6 addr(eq - fe80:0:0:0:f2de:f1ff:fe58:de16)\n"); return ret; } } } else { l3_filter.perfect_inverse_match = 0; memset(l3_filter.ip6_addr, 0, sizeof(l3_filter.ip6_addr)); } data.ptr = &l3_filter; printf("%#x:%#x:%#x:%#x:%#x:%#x:%#x:%#x\n", l3_filter.ip6_addr[0], l3_filter.ip6_addr[1], l3_filter.ip6_addr[2], l3_filter.ip6_addr[3], l3_filter.ip6_addr[4], l3_filter.ip6_addr[5], l3_filter.ip6_addr[6], l3_filter.ip6_addr[7]); ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) { printf("IOCTL Error\n"); switch (data.command_error) { case DWC_ETH_QOS_NO_HW_SUPPORT: printf("No hardware support present for IPv6 addr filtering\n"); break; default: printf("IPv6(L3) filtering is failed\n"); break; } } else printf("Successfully %s IPv6 %s %s addressing filtering on %d filter\n", (l3_filter.filter_enb_dis ? "ENABLED" : "DISABLED"), (l3_filter.perfect_inverse_match ? "INVERSE" : "PERFECT"), (l3_filter.src_dst_addr_match ? "DESTINATION" : "SOURCE"), l3_filter.filter_no); return ret; } static int config_l4_filters(int sockfd, char *ifname, char *udp_tcp, char *filter_no, char *src_dst_addr_match, char *enable_disable, char *perfect_inverse_match, char *port) { struct ifreq ifr; struct ifr_data_struct data; struct DWC_ETH_QOS_l3_l4_filter l4_filter; int ret = 0; data.flags = atoi(enable_disable); if (!strcmp(udp_tcp, "udp_filter")) data.cmd = DWC_ETH_QOS_UDP_FILTERING_CMD; else data.cmd = DWC_ETH_QOS_TCP_FILTERING_CMD; data.qInx = 0; /* Not used */ strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; l4_filter.filter_no = atoi(filter_no); l4_filter.src_dst_addr_match = atoi(src_dst_addr_match); l4_filter.filter_enb_dis = atoi(enable_disable); if (l4_filter.filter_enb_dis) { l4_filter.perfect_inverse_match = atoi(perfect_inverse_match); if (!strcmp(port, "0")) { l4_filter.port_no = 0; } else { l4_filter.port_no = atoi(port); } } else { l4_filter.perfect_inverse_match = 0; l4_filter.port_no = 0; } data.ptr = &l4_filter; printf("%d\n", l4_filter.port_no); ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) { printf("IOCTL Error\n"); switch (data.command_error) { case DWC_ETH_QOS_NO_HW_SUPPORT: printf("No hardware support present for UDP port filtering\n"); break; default: printf("UPD(L4) filtering is failed\n"); break; } } else printf("Successfully %s %s %s %s port filtering on %d filter\n", (l4_filter.filter_enb_dis ? "ENABLED" : "DISABLED"), (data.cmd == DWC_ETH_QOS_UDP_FILTERING_CMD ? "UDP" : "TCP"), (l4_filter.perfect_inverse_match ? "INVERSE" : "PERFECT"), (l4_filter.src_dst_addr_match ? "DESTINATION" : "SOURCE"), l4_filter.filter_no); return ret; } static int config_vlan_filters(int sockfd, char *ifname, char *enable_disable, char *perfect_hash_filtering, char *perfect_inverse_match) { struct ifreq ifr; struct ifr_data_struct data; struct DWC_ETH_QOS_vlan_filter vlan_filter; int ret = 0; data.flags = atoi(enable_disable); data.cmd = DWC_ETH_QOS_VLAN_FILTERING_CMD; data.qInx = 0; /* Not used */ strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; vlan_filter.filter_enb_dis = atoi(enable_disable); if (vlan_filter.filter_enb_dis) { vlan_filter.perfect_hash = atoi(perfect_hash_filtering); vlan_filter.perfect_inverse_match = atoi(perfect_inverse_match); } else { vlan_filter.perfect_hash = 0; vlan_filter.perfect_inverse_match = 0; } data.ptr = &vlan_filter; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) { printf("IOCTL Error\n"); switch (data.command_error) { case DWC_ETH_QOS_NO_HW_SUPPORT: printf("No hardware support present for VLAN filtering\n"); break; default: printf("VLAN filtering is failed\n"); break; } } else printf("Successfully %s VLAN %s filtering and %s matching\n", (vlan_filter.filter_enb_dis ? "ENABLED" : "DISABLED"), (vlan_filter.perfect_hash ? "HASH" : "PERFECT"), (vlan_filter.perfect_inverse_match ? "INVERSE" : "PERFECT")); return ret; } static int config_arp_offload(int sockfd, char *ifname, char *enable_disable) { struct ifreq ifr; struct ifr_data_struct data; int option = atoi(enable_disable); struct DWC_ETH_QOS_arp_offload arp_offload; char *ip_addr; struct sockaddr_in *addr = NULL; int ret = 0; strcpy(ifr.ifr_ifrn.ifrn_name, ifname); /* Get IP addr of our interface */ if (ioctl(sockfd, SIOCGIFADDR, &ifr) < 0) { printf("failed to get IP address of %s\n", ifname); ret = -1; goto get_ip_addr_failed; } addr = ((struct sockaddr_in *)&ifr.ifr_addr); ip_addr = inet_ntoa(addr->sin_addr); printf("IP addr to be programmed in MAC_ARP_Addr reg is %s\n", ip_addr); arp_offload.ip_addr[0] = strtol(strtok(ip_addr, "."), NULL, 10); arp_offload.ip_addr[1] = strtol(strtok(NULL, "."), NULL, 10); arp_offload.ip_addr[2] = strtol(strtok(NULL, "."), NULL, 10); arp_offload.ip_addr[3] = strtol(strtok(NULL, "."), NULL, 10); data.flags = option; data.cmd = DWC_ETH_QOS_ARP_OFFLOAD_CMD; data.qInx = 0; /* Not used */ ifr.ifr_ifru.ifru_data = &data; data.ptr = &arp_offload; printf("arp_offload.ip_addr = %d.%d.%d.%d\n", arp_offload.ip_addr[0], arp_offload.ip_addr[1], arp_offload.ip_addr[2], arp_offload.ip_addr[3]); ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) { printf("IOCTL Error\n"); switch (data.command_error) { case DWC_ETH_QOS_NO_HW_SUPPORT: printf("No hardware support present for ARP Offloading\n"); break; default: printf("ARP Offload configuration failed\n"); break; } } else printf("Successfully %s ARP Offload\n", (option ? "ENABLED" : "DISABLED")); get_ip_addr_failed: return ret; } static int config_l2_da_filtering(int sockfd, char *ifname, char *perfect_hash, char *perfect_inverse_match) { struct ifreq ifr; struct ifr_data_struct data; struct DWC_ETH_QOS_l2_da_filter l2_da_filter; int ret = 0; data.cmd = DWC_ETH_QOS_L2_DA_FILTERING_CMD; data.qInx = 0; /* Not used */ strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; l2_da_filter.perfect_hash = atoi(perfect_hash); l2_da_filter.perfect_inverse_match = atoi(perfect_inverse_match); data.ptr = &l2_da_filter; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) { printf("IOCTL Error\n"); switch (data.command_error) { case DWC_ETH_QOS_NO_HW_SUPPORT: printf("No hardware support present for L2 %s filtering\n", (l2_da_filter.perfect_hash ? "HASH" : "PERFECT")); break; default: printf("L2 filtering mode selection failed\n"); break; } } else printf("Successfully selected L2 %s filtering and %s DA matching\n", (l2_da_filter.perfect_hash ? "HASH" : "PERFECT"), (l2_da_filter.perfect_inverse_match ? "INVERSE" : "PERFECT")); get_ip_addr_failed: return ret; } /* return 0 on success and -ve on failure */ static int config_axi_pbl(int sockfd, char *ifname, char *argv1) { struct ifreq ifr; struct ifr_data_struct data; int option = atoi(argv1); int ret = 0; switch (option) { case 4: data.flags = DWC_ETH_QOS_AXI_PBL_4; break; case 8: data.flags = DWC_ETH_QOS_AXI_PBL_8; break; case 16: data.flags = DWC_ETH_QOS_AXI_PBL_16; break; case 32: data.flags = DWC_ETH_QOS_AXI_PBL_32; break; case 64: data.flags = DWC_ETH_QOS_AXI_PBL_64; break; case 128: data.flags = DWC_ETH_QOS_AXI_PBL_128; break; case 256: data.flags = DWC_ETH_QOS_AXI_PBL_256; break; default: printf("Invalid option %d\n", option); return -1; } data.cmd = DWC_ETH_QOS_AXI_PBL_CMD; data.qInx = 0; /* Not used */ strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) printf("IOCTL Error\n"); else printf("Successfully configured AXI PBL to %d\n", option); return ret; } /* return 0 on success and -ve on failure */ static int config_axi_worl(int sockfd, char *ifname, char *argv1) { struct ifreq ifr; struct ifr_data_struct data; int option = atoi(argv1); int ret = 0; if ((option > DWC_ETH_QOS_MAX_AXI_WORL) || (option < 0)) { printf("Invalid axi_worl value %d\n", option); return -1; } data.flags = (option -1); data.cmd = DWC_ETH_QOS_AXI_WORL_CMD; data.qInx = 0; /* Not used */ strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) printf("IOCTL Error\n"); else printf("Successfully configured AXI WORL to %d\n", option); return ret; } /* return 0 on success and -ve on failure */ static int config_axi_rorl(int sockfd, char *ifname, char *argv1) { struct ifreq ifr; struct ifr_data_struct data; int option = atoi(argv1); int ret = 0; if ((option > DWC_ETH_QOS_MAX_AXI_RORL) || (option < 0)) { printf("Invalid axi_rorl value %d\n", option); return -1; } data.flags = (option -1); data.cmd = DWC_ETH_QOS_AXI_RORL_CMD; data.qInx = 0; /* Not used */ strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) printf("IOCTL Error\n"); else printf("Successfully configured AXI RORL to %d\n", option); return ret; } /* return 0 on success and -ve on failure */ static int config_loopback_mode(int sockfd, char *ifname, char *argv1) { struct ifreq ifr; struct ifr_data_struct data; int option = atoi(argv1); int ret = 0; if (option) data.flags = DWC_ETH_QOS_MAC_LOOPBACK_ENABLE; else data.flags = DWC_ETH_QOS_MAC_LOOPBACK_DISABLE; data.cmd = DWC_ETH_QOS_MAC_LOOPBACK_MODE_CMD; data.qInx = 0; /* Not used */ strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret < 0) { printf("IOCTL Error\n"); switch (data.command_error) { case DWC_ETH_QOS_CONFIG_FAIL: printf("mac loopback mode is already %s\n", (option ? "enabled" : "disable")); break; } } else printf("Successfully %s mac loopback mode\n\n", (option ? "enabled" : "disabled")); if (option) printf("WARNING: Please disable the mac loopback after the testing\n" " else it will interrupt the normal operation.\n"); return ret; } /* return 0 on success and -ve on failure */ static int config_pfc(int sockfd, char *ifname, char *argv1) { struct ifreq ifr; struct ifr_data_struct data; int option = atoi(argv1); int ret = 0; if (option) data.flags = DWC_ETH_QOS_PFC_ENABLE; else data.flags = DWC_ETH_QOS_PFC_DISABLE; data.cmd = DWC_ETH_QOS_PFC_CMD; data.qInx = 0; /* Not used */ strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret == DWC_ETH_QOS_NO_HW_SUPPORT) printf("No HW support present for PFC(Priority Based Flow Control)\n"); else printf("Successfully %s PFC(Priority Based Flow Control)\n", (option ? "enabled" : "disabled")); return ret; } /* return 0 on success and -ve on failure */ static int config_dvlan_tx_processing(int sockfd, char *ifname, char *operation, char *mode, char *outer_vlt, char *inner_vlt, int is_via_reg) { struct ifreq ifr; struct ifr_data_struct data; unsigned int opn = atoi(operation); unsigned int md = ~0; unsigned int ovlt = ~0; unsigned int ivlt = ~0; struct DWC_ETH_QOS_config_dvlan conf_dvlan; int ret = 0; if ((opn < 0) && (opn > 3)) { fprintf(stderr,"Invalide - %d\n",opn); return -1; } if ((opn != 0) && !mode) { fprintf(stderr,"Please specify the ," " as operation selected is %d\n",opn); return -1; } conf_dvlan.op_type = opn; if (mode) { md = atoi(mode); if (md == 2) { if (!inner_vlt) { fprintf(stderr, "Please specify the outer & inner " "vlan tags, as mode is `Inner and Outer VLAN tag`\n"); return -1; } } else if (!outer_vlt) { fprintf(stderr, "Please specify the %s " "vlan tag, as mode is %s VLAN tag.\n", (md ? "Inner" : "Outer"), (md ? "Inner" : "Outer")); return -1; } if (inner_vlt) { ovlt = atoi(outer_vlt); ivlt = atoi(inner_vlt); fprintf(stderr, "outer_vlan_tag = %#x, inner_vlan_tag = %#x\n", ovlt, ivlt); } else if (outer_vlt) { ovlt = atoi(outer_vlt); fprintf(stderr, "outer_vlan_tag = %#x\n", ovlt); } if (md == 0) { conf_dvlan.in_out = DWC_ETH_QOS_DVLAN_OUTER; } else if (md == 1) { conf_dvlan.in_out = DWC_ETH_QOS_DVLAN_INNER; } else if (md == 2) { conf_dvlan.in_out = DWC_ETH_QOS_DVLAN_BOTH; } else { fprintf(stderr,"Invalide - %d\n",md); return -1; } } if ((opn == 0) && ((md == 2) || (!mode))) { data.flags = DWC_ETH_QOS_DVLAN_DISABLE; conf_dvlan.in_out = DWC_ETH_QOS_DVLAN_BOTH; } else { data.flags = DWC_ETH_QOS_DVLAN_ENABLE; } fprintf(stderr, "%s: operation = %d, mode = %d\n", __func__, conf_dvlan.op_type, conf_dvlan.in_out); conf_dvlan.outer_vlan_tag = ovlt; conf_dvlan.inner_vlan_tag = ivlt; conf_dvlan.via_reg_or_desc = is_via_reg; data.cmd = DWC_ETH_QOS_DVLAN_TX_PROCESSING_CMD; data.qInx = 0; /* Not used */ data.ptr = &conf_dvlan; strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret == DWC_ETH_QOS_CONFIG_FAIL) { fprintf(stderr, "IOCTL Error\n"); fprintf(stderr, "Failed to configure double VLAN processing on Tx path\n"); } else if (ret == DWC_ETH_QOS_NO_HW_SUPPORT) { fprintf(stderr, "No HW support for Single/Double VLAN\n"); } else { fprintf(stderr, "Successfully configured double VLAN processing on Tx path\n"); } return ret; } /* return 0 on success and -ve on failure */ int config_dvlan(int sockfd, int argc, char *argv[], int is_via_reg) { int ret = 0; if (argc == 4) { ret = config_dvlan_tx_processing(sockfd, argv[1], argv[3], NULL, NULL, NULL, is_via_reg); } else if (argc == 5) { ret = config_dvlan_tx_processing(sockfd, argv[1], argv[3], argv[4], argv[5], NULL, is_via_reg); } else if (argc > 5) { ret = config_dvlan_tx_processing(sockfd, argv[1], argv[3], argv[4], argv[5], argv[6], is_via_reg); } else { ret = -1; } return ret; } /* return 0 on success and -ve on failure */ static int config_dvlan_rx_processing(int sockfd, char *ifname, char *operation) { struct ifreq ifr; struct ifr_data_struct data; unsigned int opn = atoi(operation); int ret = 0; if (opn == 0) { data.flags = DWC_ETH_QOS_DVLAN_NONE; } else if (opn == 1) { data.flags = DWC_ETH_QOS_DVLAN_INNER; } else if (opn == 2) { data.flags = DWC_ETH_QOS_DVLAN_OUTER; } else if (opn == 3) { data.flags = DWC_ETH_QOS_DVLAN_BOTH; } else { fprintf(stderr,"Invalide - %d\n",opn); return -1; } data.cmd = DWC_ETH_QOS_DVLAN_RX_PROCESSING_CMD; data.qInx = 0; /* Not used */ strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret == DWC_ETH_QOS_CONFIG_FAIL) { fprintf(stderr, "IOCTL Error\n"); fprintf(stderr, "Failed to configure double VLAN processing on Rx path\n"); } else if (ret == DWC_ETH_QOS_NO_HW_SUPPORT) { fprintf(stderr, "No HW support for Single/Double VLAN\n"); } else { fprintf(stderr, "Successfully configured double VLAN processing on Rx path\n"); } return ret; } /* return 0 on success and -ve on failure */ static int config_svlan(int sockfd, char *ifname, char *operation) { struct ifreq ifr; struct ifr_data_struct data; unsigned int opn = atoi(operation); int ret = 0; if (opn == 0) { data.flags = DWC_ETH_QOS_DVLAN_NONE; } else if (opn == 1) { data.flags = DWC_ETH_QOS_DVLAN_INNER; } else if (opn == 2) { data.flags = DWC_ETH_QOS_DVLAN_OUTER; } else if (opn == 3) { data.flags = DWC_ETH_QOS_DVLAN_BOTH; } else { fprintf(stderr,"Invalide - %d\n",opn); return -1; } data.cmd = DWC_ETH_QOS_SVLAN_CMD; data.qInx = 0; /* Not used */ strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret == DWC_ETH_QOS_CONFIG_FAIL) { fprintf(stderr, "IOCTL Error\n"); fprintf(stderr, "Error in configuring S-VLAN\n"); } else if (ret == DWC_ETH_QOS_NO_HW_SUPPORT) { fprintf(stderr, "No HW support for Single/Double VLAN\n"); } else { fprintf(stderr, "Successfully configured S-VLAN\n"); } return ret; } /* return 0 on success and -ve on failure */ static int config_ptpoffloading(int sockfd, char *ifname, char *en_dis, char *mode, char *domain_num, char *multicast_or_unicast) { struct ifreq ifr; struct ifr_data_struct data; unsigned int en_dis_flag = atoi(en_dis); unsigned int md; unsigned int mc_uc; int ret = 0; struct DWC_ETH_QOS_config_ptpoffloading conf_ptp; if (en_dis_flag == 0) { conf_ptp.en_dis = DWC_ETH_QOS_PTP_OFFLOADING_DISABLE; } else if (en_dis_flag == 1) { conf_ptp.en_dis = DWC_ETH_QOS_PTP_OFFLOADING_ENABLE; if ((!mode) || (!domain_num)) { fprintf(stderr,"Missing an argument and/or \n"); return -1; } } else { fprintf(stderr,"Invalide option - %d\n",en_dis_flag); return -1; } if (en_dis_flag) { md = atoi(mode); if ((md < 0) && (md > 6)) { fprintf(stderr,"Invalide mode - %d\n",md); return -1; } conf_ptp.mode = md; conf_ptp.domain_num = atoi(domain_num); mc_uc = atoi(multicast_or_unicast); if((mc_uc < 0) || (mc_uc > 1)) { fprintf(stderr,"Invalide multicast_or_unicast parameter - %d\n", mc_uc); return -1; } conf_ptp.mc_uc = mc_uc; } data.cmd = DWC_ETH_QOS_PTPOFFLOADING_CMD; data.qInx = 0; /* Not used */ data.ptr = &conf_ptp; strcpy(ifr.ifr_ifrn.ifrn_name, ifname); ifr.ifr_ifru.ifru_data = &data; ret = ioctl(sockfd, DWC_ETH_QOS_PRV_IOCTL, &ifr); if (ret == DWC_ETH_QOS_CONFIG_FAIL) { fprintf(stderr, "IOCTL Error\n"); fprintf(stderr, "Error in configuring PTP Offloading.\n"); } else if (ret == DWC_ETH_QOS_NO_HW_SUPPORT) { fprintf(stderr, "No PTP support in Hardware.\n"); } else { fprintf(stderr, "Successfully configured PTP Offloading.\n"); } return ret; } void usage_common(char *cmd) { if (print_all) { fprintf(stderr, " %s",cmd); } else { fprintf(stderr, "\n %s %s %s \n\n", exe_name, (if_name ? if_name : ""), (cmd ? cmd : "")); fprintf(stderr, " supported parameters ::\n"); } } void usage_qInx() { if (!print_all) fprintf(stderr, " is DMA channel number, it can be 0, " "1, 2, 3, 4, 5, 6, and 7\n\n"); } void usage_dvlan_tx_via_reg() { usage_common("dvlan_tx_via_reg"); fprintf(stderr, " \n" " [operation\n" " 0 - None, 1 - Deletion, 2 - Insertion, 3 - Replacement\n" " mode\n" " 0 - Outer VLAN, 1 - Inner VLAN, 2 - both Inner and Outer VLAN\n" " outer_vlan_tag\n" " Outer VLAN tag value, including VLAN priority\n" " inner_vlan_tag\n" " Inner VLAN tag value, including VLAN priority]\n" "\n"); } void usage_dvlan_tx_via_desc() { usage_common("dvlan_tx_via_desc"); fprintf(stderr, " \n" " [operation\n" " 0 - None, 1 - Deletion, 2 - Insertion, 3 - Replacement\n" " mode\n" " 0 - Outer VLAN, 1 - Inner VLAN, 2 - both Inner and Outer VLAN\n" " outer_vlan_tag\n" " Outer VLAN tag value, including VLAN priority\n" " inner_vlan_tag\n" " Inner VLAN tag value, including VLAN priority]\n" "\n"); } void usage_dvlan_rx() { usage_common("dvlan_rx"); fprintf(stderr, " \n" " [operation\n" " 0 - no vlan stripping.\n" " 1 - Inner VLAN stripping only\n" " 2 - Outer VLAN stripping only\n" " 3 - Both Inner and Outer VLAN stripping]\n" "\n"); } void usage_svlan_en() { usage_common("svlan_en"); fprintf(stderr, " \n" " [operation\n" " 0 - disable S-VLAN\n" " 1 - enable S-VLAN for Inner VLAN\n" " 2 - enable S-VLAN for Outer VLAN\n" " 3 - enable S-VLAN for both Inner and Outer VLAN]\n" "\n"); } void usage_ptp_offload() { usage_common("ptp_offload"); fprintf(stderr, " \n" " [disable/enable\n" " 0 - to disable ptp offloading\n" " 1 - to enable ptp offloading\n" " mode\n" " 1 - Ordinary or Boundary Slave\n" " 2 - Ordinary or Boundary Master\n" " 3 - Transparent Slave\n" " 4 - Transparent Master\n" " 5 - Peer-to-Peer Transparent\n" " ptp_domain_num\n" " PTP domain number]\n" " multicast_or_unicast\n" " 0 - multicast address]\n" " 1 - unicast address]\n" "\n"); } void usage_rxoutervlanstrip() { usage_common("rxoutervlanstrip"); fprintf(stderr, " <0|1|2|3>\n" " [0 - don't strip, 1 - strip if VLAN filter pass,\n" " 2 - strip if VLAN filter fail, 3 - strip always]\n" "\n"); } void usage_rxinnervlanstrip() { usage_common("rxinnervlanstrip"); fprintf(stderr, " <0|1|2|3>\n" " [0 - don't strip, 1 - strip if VLAN filter pass,\n" " 2 - strip if VLAN filter fail, 3 - strip always]\n" "\n"); } void usage_txvlan_desc() { usage_common("txvlan_desc"); fprintf(stderr, " <0|1|2|3>\n" " [0 - No deletion/insertion/replacement, 1 - deletion,\n" " 2 - insertion 3 - replacement]\n" "\n"); } void usage_txvlan_reg() { usage_common("txvlan_reg"); fprintf(stderr, " <0|1|2|3>\n" " [0 - No deletion/insertion/replacement, 1 - deletion,\n" " 2 - insertion 3 - replacement]\n" "\n"); } void usage_sa0_desc() { usage_common("sa0_desc"); fprintf(stderr, " <0|1|2>\n" " [0 - Do not include source address,\n" " 1 - include/insert source address,\n" " 2 - replace the source address]\n" "\n"); } void usage_sa1_desc() { usage_common("sa1_desc"); fprintf(stderr, " <0|1|2>\n" " [0 - Do not include source address,\n" " 1 - include/insert source address,\n" " 2 - replace the source address]\n" "\n"); } void usage_sa0_reg() { usage_common("sa0_reg"); fprintf(stderr, " <0|1|2>\n" " [0 - Do not include source address,\n" " 1 - include/insert source address,\n" " 2 - replace the source address]\n" "\n"); } void usage_sa1_reg() { usage_common("sa1_reg"); fprintf(stderr, " <0|1|2>\n" " [0 - Do not include source address,\n" " 1 - include/insert source address,\n" " 2 - replace the source address]\n" "\n"); } void usage_powerup() { usage_common("powerup"); fprintf(stderr, " \n" " [Gets the device out of powerdown mode (Allowed only if h/w supports\n" " wake up on magic packet or remote wakeup)]\n" "\n"); } void usage_powerdown() { usage_common("powerdown"); fprintf(stderr, " \n" " [Puts the device in powerdown mode. Device will powerup on manual 'powerup'\n" " or on receiving magic packet/remote wakeup packet (Allowed only if\n" " h/w supports wake up on magic packet or remote wakeup)]\n" "\n"); } void usage_rx_threshold() { usage_common("rx_threshold"); fprintf(stderr, " <32|64|96|128> Bytes [To configure RX FIFO Threshold]\n" "\n"); } void usage_tx_threshold() { usage_common("tx_threshold"); fprintf(stderr, " <32|64|96|128|192|256|384|512> Bytes [To configure TX FIFO Threshold]\n" "\n"); } void usage_rsf() { usage_common("rsf"); fprintf(stderr, " <0|1> [0 - disable Receive Store and Forward Mode,\n" " 1 - enable Receive Store and Forward Mode]\n" "\n"); } void usage_tsf() { usage_common("tsf"); fprintf(stderr, " <0|1> [0 - disable Transmit Store and Forward Mode,\n" " 1 - enable Transmit Store and Forward Mode]\n" "\n"); } void usage_osf() { usage_common("osf"); fprintf(stderr, " <0|1> [0 - disable Transmit DMA to Operate on Second Frame,\n" " 1 - enable Transmit DMA to Operate on Second Frame]\n" "\n"); } void usage_incrx_incr() { usage_common("incrx_incr"); fprintf(stderr, " <0|1> [0 - select INCRX mode, 1 - select INCR mode]\n" "\n"); } void usage_axi_pbl() { usage_common("axi_pbl"); fprintf(stderr, " <4|8|16|32|64|128|256> [To configure AXI PBL]\n" "\n"); } void usage_axi_worl() { usage_common("axi_worl"); fprintf(stderr, " <1 to 31> [To configure AXI Maximum Write Outstanding Request Limit]\n" "\n"); } void usage_axi_rorl() { usage_common("axi_rorl"); fprintf(stderr, " <1 to 31> [To configure AXI Maximum Read Outstanding Request Limit]\n" "\n"); } void usage_rx_pbl() { usage_common("rx_pbl"); fprintf(stderr, " <1|2|4|8|16|32|128|256> [To configre RX DMA PBL]\n" "\n"); } void usage_tx_pbl() { usage_common("tx_pbl"); fprintf(stderr, " <1|2|4|8|16|32|128|256> [To configre TX DMA PBL]\n" "\n"); } void usage_context() { usage_common("context"); fprintf(stderr, " <0|1>\n" " [1 to setup a context descriptor with every normal descriptor\n" " 0 to set context descriptor only when VLAN ID Changes]\n" "\n"); } void usage_queue_count() { usage_common("queue_count"); fprintf(stderr, " [Displays number of Tx and Rx Queues/Channels supported by hardware]\n" "\n"); } void usage_dcb() { usage_common("dcb"); fprintf(stderr, " \n" " [algorithm_value\n" " 0 - WRR (Weighted Round Robin)\n" " 1 - WFQ (Weighted Fair Queuing)\n" " 2 - DWRR (Deficit Weighted Round Robin)\n" " 3 - SP (Strict Priority)\n" " weights - value in terms of percentage of BW to be allocated\n" " max-frame-size - maximum frame size]\n" " NOTE:\n" " \"max-frame-size\" is applicable for DWRR only\n" " \"weigths\" are ignored for SP\n" "\n"); } void usage_avb() { usage_common("avb"); fprintf(stderr, " \n" " [algorithm value\n" " 0 - SP (Strict Priority)\n" " 1 - CBS (Credit Based Shaper)\n" " BW - value in terms of percentage of BW to be allocated\n" " credit_control\n" " 0 - disabled credit_control\n" " 1 - enabled credit_control]\n" " NOTE:\n" " \"credit_control\" is applicable for CBS only\n" "\n"); } void usage_split_hdr() { usage_common("split_hdr"); fprintf(stderr, " <0|1>\n" " [0 - disable split header, 1 - enable split header]\n" "\n"); } void usage_l3_l4_filter() { usage_common("l3_l4_filter"); fprintf(stderr, " <0/1>\n" " [0 - disable l3/l4 filtering, 1 - enable l3/l4 filtering]\n" "\n"); } void usage_ip4_filter() { usage_common("ip4_filter"); fprintf(stderr, " \n" " [filter_no - 0, 1, 2, 3, 4, 5, 6, or 7\n" " src/dst addr\n" " 0 - src addr match, 1 - dst addr match\n" " enable/disable\n" " 0 - to disable filter, 1 - to enable filter\n" " perfect/inverse\n" " 0 - perfect match, 1 - inverse match\n" " ip - IP address(eq-192.168.1.10)]\n" "\n"); } void usage_ip6_filter() { usage_common("ip6_filter"); fprintf(stderr, " \n" " [filter_no - 0, 1, 2, 3, 4, 5, 6, or 7\n" " src/dst addr\n" " 0 - src addr match, 1 - dst addr match\n" " enable/disable\n" " 0 - to disable filter, 1 - to enable filter\n" " perfect/inverse\n" " 0 - perfect match, 1 - inverse match\n" " ip - IP address(eq - fe80:0:0:0:f2de:f1ff:fe58:de16)]\n" "\n"); } void usage_udp_filter() { usage_common("udp_filter"); fprintf(stderr, " \n" " [filter_no - 0, 1, 2, 3, 4, 5, 6, or 7\n" " src/dst port\n" " 0 - src port match, 1 - dst port match\n" " enable/disable\n" " 0 - to disable filter, 1 - to enable filter\n" " perfect/inverse\n" " 0 - perfect match, 1 - inverse match\n" " port_no - port number to be matched]\n" "\n"); } void usage_tcp_filter() { usage_common("tcp_filter"); fprintf(stderr, " \n" " [filter_no - 0, 1, 2, 3, 4, 5, 6, or 7\n" " src/dst port\n" " 0 - src port match, 1 - dst port match\n" " enable/disable\n" " 0 - to disable filter, 1 - to enable filter\n" " perfect/inverse\n" " 0 - perfect match, 1 - inverse match\n" " port_no - port number to be matched]\n" "\n"); } void usage_vlan_filter() { usage_common("vlan_filter"); fprintf(stderr, " \n" " [enable/disable\n" " 0 - to disable, 1 - to enable VLAN filtering\n" " perfect/hash filtering\n" " 0 - perfect filtering, 1 - hash filtering\n" " perfect/inverse matching\n" " 0 - perfect matching, 1 - inverse matching]\n" "\n"); } void usage_l2_da_filter() { usage_common("l2_da_filter"); fprintf(stderr, " \n" " [perfect/hash filtering\n" " 0 - perfect filtering, 1 - hash filtering]\n" " perfect/inverse matching\n" " 0 - perfect matching, 1 - inverse matching]\n" "\n"); } void usage_arp() { usage_common("arp"); fprintf(stderr, " \n" " [enable/disable\n" " 0 - to disable, 1 - to enable]\n" "\n"); } void usage_mac_lb() { usage_common("mac_lb"); fprintf(stderr, " <0|1>\n" " [0 - to disable mac loopback, 1 - to enable mac loopback]\n\n" " WARNING: Please disable the mac loopback after the testing\n" " else it will interrupt the normal operation.\n" "\n"); } void usage_pfc() { usage_common("pfc"); fprintf(stderr, " \n" " [enable/disable\n" " 0 - to disable, 1 - to enable]\n" "\n"); } void print_all_usage() { fprintf(stderr, "\nUsage:\n" " %s \n\n",exe_name); print_all = 1; usage_qInx(); usage_rxoutervlanstrip(); usage_rxinnervlanstrip(); usage_txvlan_desc(); usage_txvlan_reg(); usage_sa0_desc(); usage_sa1_desc(); usage_sa0_reg(); usage_sa1_reg(); usage_powerup(); usage_powerdown(); usage_rx_threshold(); usage_tx_threshold(); usage_rsf(); usage_tsf(); usage_osf(); usage_incrx_incr(); usage_axi_pbl(); usage_axi_worl(); usage_axi_rorl(); usage_rx_pbl(); usage_tx_pbl(); usage_context(); usage_queue_count(); usage_dcb(); usage_avb(); usage_split_hdr(); usage_l3_l4_filter(); usage_ip4_filter(); usage_ip6_filter(); usage_udp_filter(); usage_tcp_filter(); usage_vlan_filter(); usage_l2_da_filter(); usage_arp(); usage_mac_lb(); usage_pfc(); usage_dvlan_tx_via_reg(); usage_dvlan_tx_via_desc(); usage_dvlan_rx(); usage_svlan_en(); usage_ptp_offload(); print_all = 0; } main(int argc, char *argv[]) { int ret = 0; int sockfd; exe_name = strdup(argv[0]); if (argc >= 3) { sockfd = open_socket(argv[1]); if_name = strdup(argv[1]); if (sockfd < 0) { printf("unable to open %s socket\n", argv[1]); return sockfd; } tx_queue_count = DWC_ETH_QOS_get_tx_qcnt(sockfd, argv[1]); rx_queue_count = DWC_ETH_QOS_get_rx_qcnt(sockfd, argv[1]); connected_speed = DWC_ETH_QOS_get_connected_speed(sockfd, argv[1]); if (0 == strcmp(argv[2], "powerdown")) { if (argc < 4) { usage_powerdown(); goto argc_failed; } ret = powerdown_device(sockfd, argv[1], argv[3]); } else if (0 == strcmp(argv[2], "powerup")) { if (argc < 4) { usage_powerup(); goto argc_failed; } ret = powerup_device(sockfd, argv[1], argv[3]); } else if (0 == strcmp(argv[2], "rx_threshold")) { if (argc < 5) { usage_rx_threshold(); goto argc_failed; } ret = config_rx_threshold(sockfd, argv[1], argv[3], argv[4]); } else if (0 == strcmp(argv[2], "tx_threshold")) { if (argc < 5) { usage_tx_threshold(); goto argc_failed; } ret = config_tx_threshold(sockfd, argv[1], argv[3], argv[4]); } else if (0 == strcmp(argv[2], "rsf")) { if (argc < 5) { usage_rsf(); goto argc_failed; } ret = config_rsf(sockfd, argv[1], argv[3], argv[4]); } else if (0 == strcmp(argv[2], "tsf")) { if (argc < 5) { usage_tsf(); goto argc_failed; } ret = config_tsf(sockfd, argv[1], argv[3], argv[4]); } else if (0 == strcmp(argv[2], "osf")) { if (argc < 5) { usage_osf(); goto argc_failed; } ret = config_osf(sockfd, argv[1], argv[3], argv[4]); } else if (0 == strcmp(argv[2], "incrx_incr")) { if (argc < 4) { usage_incrx_incr(); goto argc_failed; } ret = config_incrx_incr(sockfd, argv[1], argv[3]); } else if (0 == strcmp(argv[2], "rx_pbl")) { if (argc < 5) { usage_rx_pbl(); goto argc_failed; } ret = config_rx_pbl(sockfd, argv[1], argv[3], argv[4]); } else if (0 == strcmp(argv[2], "tx_pbl")) { if (argc < 5) { usage_tx_pbl(); goto argc_failed; } ret = config_tx_pbl(sockfd, argv[1], argv[3], argv[4]); } #if 0 else if (0 == strcmp(argv[2], "rxoutervlanstrip")) { if (argc < 4) { usage_rxoutervlanstrip(); goto argc_failed; } ret = rx_outer_vlan_strip(sockfd, argv[1], argv[3]); } #endif else if (0 == strcmp(argv[2], "dvlan_tx_via_reg")) { if (argc < 4) { usage_dvlan_tx_via_reg(); goto argc_failed; } ret = config_dvlan(sockfd, argc, argv, DWC_ETH_QOS_VIA_REG); } else if (0 == strcmp(argv[2], "dvlan_tx_via_desc")) { if (argc < 4) { usage_dvlan_tx_via_desc(); goto argc_failed; } ret = config_dvlan(sockfd, argc, argv, DWC_ETH_QOS_VIA_DESC); } else if (0 == strcmp(argv[2], "dvlan_rx")) { if (argc != 4) { usage_dvlan_rx(); goto argc_failed; } ret = config_dvlan_rx_processing(sockfd, argv[1], argv[3]); } else if (0 == strcmp(argv[2], "svlan_en")) { if (argc != 4) { usage_svlan_en(); goto argc_failed; } ret = config_svlan(sockfd, argv[1], argv[3]); } else if (0 == strcmp(argv[2], "ptp_offload")) { if (argc < 5) { usage_ptp_offload(); goto argc_failed; } if (argc == 4) ret = config_ptpoffloading(sockfd, argv[1], argv[3], NULL, NULL, NULL); else if (argc > 4) ret = config_ptpoffloading(sockfd, argv[1], argv[3], argv[4], argv[5], argv[6]); } #if 0 else if (0 == strcmp(argv[2], "rxinnervlanstrip")) { if (argc < 4) { usage_rxinnervlanstrip(); goto argc_failed; } ret = rx_inner_vlan_strip(sockfd, argv[1], argv[3]); } else if (0 == strcmp(argv[2], "txvlan_desc")) { if (argc < 5) { usage_txvlan_desc(); goto argc_failed; } ret = tx_vlan_ctrl_via_desc(sockfd, argv[1], argv[3], argv[4]); } else if (0 == strcmp(argv[2], "txvlan_reg")) { if (argc < 5) { usage_txvlan_reg(); goto argc_failed; } ret = tx_vlan_ctrl_via_reg(sockfd, argv[1], argv[3], argv[4]); } #endif else if (0 == strcmp(argv[2], "sa0_desc")) { if (argc < 4) { usage_sa0_desc(); goto argc_failed; } ret = sa0_ctrl_via_desc(sockfd, argv[1], argv[3]); } else if (0 == strcmp(argv[2], "sa1_desc")) { if (argc < 4) { usage_sa1_desc(); goto argc_failed; } ret = sa1_ctrl_via_desc(sockfd, argv[1], argv[3]); } else if (0 == strcmp(argv[2], "sa0_reg")) { if (argc < 4) { usage_sa0_reg(); goto argc_failed; } ret = sa0_ctrl_via_reg(sockfd, argv[1], argv[3]); } else if (0 == strcmp(argv[2], "sa1_reg")) { if (argc < 4) { usage_sa1_reg(); goto argc_failed; } ret = sa1_ctrl_via_reg(sockfd, argv[1], argv[3]); } else if (0 == strcmp(argv[2], "queue_count")) { DWC_ETH_QOS_get_rx_qcnt(sockfd, argv[1]); DWC_ETH_QOS_get_tx_qcnt(sockfd, argv[1]); } else if (0 == strcmp(argv[2], "context")) { if (argc < 5) { usage_context(); goto argc_failed; } ret = setup_context_descriptor(sockfd, argv[1], argv[3], argv[4]); } else if (0 == strcmp(argv[2], "dcb")) { if (argc < 7) { usage_dcb(); goto argc_failed; } ret = program_dcb_algorithm(sockfd, argv[1], argv[3], argv[4], argv[5], argv[6]); } else if (0 == strcmp(argv[2], "avb")) { if (argc < 7) { usage_avb(); goto argc_failed; } ret = program_avb_algorithm(sockfd, argv[1], argv[3], argv[4], argv[5], argv[6]); } else if (0 == strcmp(argv[2], "split_hdr")) { if (argc < 4) { usage_split_hdr(); goto argc_failed; } ret = config_rx_split_hdr(sockfd, argv[1], argv[3]); } else if (0 == strcmp(argv[2], "l3_l4_filter")) { if (argc < 4) { usage_l3_l4_filter(); goto argc_failed; } ret = config_l3_l4_filter(sockfd, argv[1], argv[3]); } else if (0 == strcmp(argv[2], "ip4_filter")) { if (argc < 5) { usage_ip4_filter(); goto argc_failed; } if (!strcmp(argv[5], "1")) { if (argc != 8) { usage_ip4_filter(); goto argc_failed; } ret = config_ipv4_filters(sockfd, argv[1], argv[3], argv[4], argv[5], argv[6], argv[7]); } else { ret = config_ipv4_filters(sockfd, argv[1], argv[3], argv[4], argv[5], NULL, NULL); } } else if (0 == strcmp(argv[2], "ip6_filter")) { if (argc < 5) { usage_ip6_filter(); goto argc_failed; } if (!strcmp(argv[5], "1")) { if (argc != 8) { usage_ip6_filter(); goto argc_failed; } ret = config_ipv6_filters(sockfd, argv[1], argv[3], argv[4], argv[5], argv[6], argv[7]); } else { ret = config_ipv6_filters(sockfd, argv[1], argv[3], argv[4], argv[5], NULL, NULL); } } else if ((0 == strcmp(argv[2], "udp_filter") || (0 == strcmp(argv[2], "tcp_filter")))) { if (argc < 5) { if (0 == strcmp(argv[2], "tcp_filter")) usage_tcp_filter(); else usage_udp_filter(); goto argc_failed; } if (!strcmp(argv[5], "1")) { if (argc != 8) { if (0 == strcmp(argv[2], "tcp_filter")) usage_tcp_filter(); else usage_udp_filter(); goto argc_failed; } ret = config_l4_filters(sockfd, argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7]); } else { ret = config_l4_filters(sockfd, argv[1], argv[2], argv[3], argv[4], argv[5], NULL, NULL); } } else if (0 == strcmp(argv[2], "vlan_filter")) { if (argc < 4) { usage_vlan_filter(); goto argc_failed; } if (!strcmp(argv[3], "1")) { if (argc != 6) { usage_vlan_filter(); goto argc_failed; } ret = config_vlan_filters(sockfd, argv[1], argv[3], argv[4], argv[5]); } else { ret = config_vlan_filters(sockfd, argv[1], argv[3], NULL, NULL); } } else if (0 == strcmp(argv[2], "l2_da_filter")) { if (argc < 5) { usage_l2_da_filter(); goto argc_failed; } ret = config_l2_da_filtering(sockfd, argv[1], argv[3], argv[4]); } else if (0 == strcmp(argv[2], "arp")) { if (argc < 4) { usage_arp(); goto argc_failed; } ret = config_arp_offload(sockfd, argv[1], argv[3]); } else if (0 == strcmp(argv[2], "axi_pbl")) { if (argc < 4) { usage_axi_pbl(); goto argc_failed; } ret = config_axi_pbl(sockfd, argv[1], argv[3]); } else if (0 == strcmp(argv[2], "axi_worl")) { if (argc < 4) { usage_axi_worl(); goto argc_failed; } ret = config_axi_worl(sockfd, argv[1], argv[3]); } else if (0 == strcmp(argv[2], "axi_rorl")) { if (argc < 4) { usage_axi_rorl(); goto argc_failed; } ret = config_axi_rorl(sockfd, argv[1], argv[3]); } else if (0 == strcmp(argv[2], "mac_lb")) { if (argc < 4) { usage_mac_lb(); goto argc_failed; } ret = config_loopback_mode(sockfd, argv[1], argv[3]); } else if (0 == strcmp(argv[2], "pfc")) { if (argc < 4) { usage_pfc(); goto argc_failed; } ret = config_pfc(sockfd, argv[1], argv[3]); } else { print_all_usage(); } close_socket(sockfd); } else { print_all_usage(); } return ret; argc_failed: printf("PLEASE SPECIFY CORRECT NUMBER OF ARGUMENTS\n"); close_socket(sockfd); }