| /* |
| * |
| * Copyright (C) 2007 Mindspeed Technologies, Inc. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; either version 2 of the License, or |
| * (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program; if not, write to the Free Software |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| */ |
| |
| #include "cmm.h" |
| #include "fpp.h" |
| #include <ctype.h> |
| #include <limits.h> |
| |
| /************************************************************ |
| * |
| * |
| * |
| ************************************************************/ |
| void cmmQmShowPrintHelp() |
| { |
| cmm_print(DEBUG_STDOUT, "show qm not yet supported\n"); |
| } |
| |
| |
| /************************************************************ |
| * |
| * |
| * |
| ************************************************************/ |
| int cmmQmShowProcess(char ** keywords, int tabStart, daemon_handle_t daemon_handle) |
| { |
| |
| //help: |
| cmmQmShowPrintHelp(); |
| return -1; |
| } |
| |
| int cmmQmExptRateQueryProcess(char ** keywords, int tabStart, daemon_handle_t daemon_handle) |
| { |
| int cpt = tabStart; |
| int rcvBytes = 0; |
| char rcvBuffer[256]; |
| short rc; |
| fpp_qm_expt_rate_cmd_t *pExptRateCmd = ( fpp_qm_expt_rate_cmd_t *)rcvBuffer; |
| |
| #ifdef COMCERTO_2000 |
| if(!keywords[cpt]) |
| goto help; |
| |
| if (strcasecmp(keywords[cpt], "eth") == 0) |
| pExptRateCmd->if_type = FPP_EXPT_TYPE_ETH; |
| else if (strcasecmp(keywords[cpt], "wifi") == 0) |
| pExptRateCmd->if_type = FPP_EXPT_TYPE_WIFI; |
| else if (strcasecmp(keywords[cpt], "arp_ndp") == 0) |
| pExptRateCmd->if_type = FPP_EXPT_TYPE_ARP; |
| else if (strcasecmp(keywords[cpt], "pcap") == 0) |
| pExptRateCmd->if_type = FPP_EXPT_TYPE_PCAP; |
| else |
| goto help; |
| #endif |
| |
| rcvBytes = cmmSendToDaemon(daemon_handle, FPP_CMD_QM_QUERY_EXPT_RATE , |
| pExptRateCmd, sizeof(fpp_qm_expt_rate_cmd_t) , rcvBuffer); |
| |
| if (rcvBytes < sizeof( fpp_qm_expt_rate_cmd_t) ) { |
| rc = (rcvBytes < sizeof(unsigned short) ) ? 0 : |
| *((unsigned short *) rcvBuffer); |
| if (rc == FPP_ERR_UNKNOWN_ACTION) { |
| cmm_print(DEBUG_STDERR, "ERROR: doess not support ACTION_QUERY\n"); |
| } else { |
| cmm_print(DEBUG_STDERR, "ERROR: Unexpected result returned from FPP rc:%d\n", rc); |
| } |
| return CLI_OK; |
| } |
| |
| cmm_print(DEBUG_STDOUT, "QM Exception RATE (packets/sec): %d\n", |
| (pExptRateCmd->pkts_per_msec * 1000)); |
| |
| return CLI_OK; |
| help: |
| cmm_print(DEBUG_STDOUT, "Usage: query qmexptrate {eth | wifi}\n"); |
| |
| return CLI_OK; |
| } |
| |
| |
| #define NUM_INTERFACES GEM_PORTS |
| |
| |
| /************************************************************ |
| * |
| * |
| * |
| ************************************************************/ |
| int cmmQmQueryProcess(char ** keywords, int tabStart, daemon_handle_t daemon_handle) |
| { |
| int rcvBytes = 0,i,j,k,len=0; |
| char rcvBuffer[256]; |
| short rc; |
| fpp_qm_query_cmd_t *pQmQuery = ( fpp_qm_query_cmd_t *)rcvBuffer; |
| char output_buf[256]; |
| |
| |
| cmm_print(DEBUG_STDOUT, "QM details:\n"); |
| cmm_print(DEBUG_STDOUT, "---------- \n"); |
| for (i = 0 ; i < NUM_INTERFACES; i++) |
| { |
| char ifname[IFNAMSIZ]; |
| |
| memset(rcvBuffer,0,256); |
| |
| pQmQuery->port = i; |
| rcvBytes = cmmSendToDaemon(daemon_handle,FPP_CMD_QM_QUERY , |
| pQmQuery, sizeof(fpp_qm_query_cmd_t) , rcvBuffer); |
| |
| if (rcvBytes != sizeof(fpp_qm_query_cmd_t) ) { |
| rc = (rcvBytes < sizeof(unsigned short) ) ? 0 : |
| *((unsigned short *) rcvBuffer); |
| if (rc == FPP_ERR_UNKNOWN_ACTION) { |
| cmm_print(DEBUG_STDERR, "ERROR: doess not support ACTION_QUERY\n"); |
| } else { |
| cmm_print(DEBUG_STDERR, "ERROR: Unexpected result returned from FPP rc:%d\n", rc); |
| } |
| return CLI_OK; |
| } |
| |
| cmm_print(DEBUG_STDOUT, "Interface : %s\n", get_port_name(pQmQuery->port, ifname, IFNAMSIZ)); |
| |
| if (pQmQuery->queue_qosenable_mask != 0) { |
| #ifdef COMCERTO_2000 |
| cmm_print(DEBUG_STDOUT, "QOS: Enabled : \n"); |
| #else |
| cmm_print(DEBUG_STDOUT, "QOS: Enabled on queue(s): \n"); |
| for (j=0; j < FPP_NUM_QUEUES; j++) |
| { |
| if(pQmQuery->queue_qosenable_mask & (1 << j)) |
| len += sprintf(output_buf+len, "%d ", j); |
| } |
| cmm_print(DEBUG_STDOUT, "%s \n",output_buf); |
| #endif |
| } |
| else |
| cmm_print(DEBUG_STDOUT, "QOS: Disabled \n"); |
| |
| |
| cmm_print(DEBUG_STDOUT, "Maximum Tx Depth = %d \n", pQmQuery->max_txdepth); |
| |
| cmm_print(DEBUG_STDOUT, "Shaper details:\n"); |
| cmm_print(DEBUG_STDOUT, "---------- \n"); |
| for (j =0; j < FPP_NUM_SHAPERS; j++) |
| { |
| len=0; |
| cmm_print(DEBUG_STDOUT, "Shaper %d:\n", j); |
| |
| if(pQmQuery->shaper_qmask[j] == 0) |
| cmm_print(DEBUG_STDOUT, "No Queues attached\n"); |
| else |
| { |
| cmm_print(DEBUG_STDOUT, "The following queue(s) are attached: \n"); |
| for (k=0; k < FPP_NUM_QUEUES; k++) |
| { |
| if(pQmQuery->shaper_qmask[j] & (1 << k)) |
| len += sprintf(output_buf+len, "%d ", k); |
| } |
| cmm_print(DEBUG_STDOUT, "%s \n",output_buf); |
| } |
| |
| cmm_print(DEBUG_STDOUT, "Tokens Per Clock Period %d \n", pQmQuery->tokens_per_clock_period[j]); |
| cmm_print(DEBUG_STDOUT, "Bucket Size %d \n", pQmQuery->bucket_size[j]); |
| |
| } |
| cmm_print(DEBUG_STDOUT, "---------- \n"); |
| |
| cmm_print(DEBUG_STDOUT, "Scheduler details:\n"); |
| cmm_print(DEBUG_STDOUT, "---------- \n"); |
| for (j =0; j < FPP_NUM_SCHEDULERS; j++) |
| { |
| len=0; |
| cmm_print(DEBUG_STDOUT, "Scheduler %d:\n", j); |
| |
| if(pQmQuery->sched_qmask[j] == 0) |
| cmm_print(DEBUG_STDOUT, "No Queues attached\n"); |
| else |
| { |
| cmm_print(DEBUG_STDOUT, "The following queue(s) are attached: \n"); |
| for (k=0; k < FPP_NUM_QUEUES; k++) |
| { |
| if(pQmQuery->sched_qmask[j] & (1 << k)) |
| len += sprintf(output_buf+len, "%d ", k); |
| } |
| cmm_print(DEBUG_STDOUT, "%s \n",output_buf); |
| } |
| |
| switch (pQmQuery->sched_alg[j]) |
| { |
| case 0: |
| cmm_print(DEBUG_STDOUT, "ALG : PQ \n"); |
| break; |
| case 1: |
| cmm_print(DEBUG_STDOUT, "ALG :CBWFQ \n"); |
| break; |
| case 2: |
| cmm_print(DEBUG_STDOUT, "ALG :DWRR \n"); |
| break; |
| default: |
| cmm_print(DEBUG_STDOUT, "ALG :NONE \n"); |
| break; |
| } |
| |
| } |
| cmm_print(DEBUG_STDOUT, "---------- \n"); |
| |
| cmm_print(DEBUG_STDOUT, "Queue details:\n"); |
| cmm_print(DEBUG_STDOUT, "---------- \n"); |
| for (j =0; j < FPP_NUM_QUEUES; j++) |
| { |
| len=0; |
| len += sprintf(output_buf+len, "Queue %d: ", j); |
| len += sprintf(output_buf+len, "Max Queue Depth %d ", pQmQuery->max_qdepth[j]); |
| cmm_print(DEBUG_STDOUT, "%s \n",output_buf); |
| } |
| cmm_print(DEBUG_STDOUT, "\n---------- \n"); |
| |
| |
| |
| cmm_print(DEBUG_STDOUT,"--------------------------------------------------\n"); |
| } |
| |
| return CLI_OK; |
| |
| } |
| |
| |
| /************************************************************ |
| * |
| * |
| * |
| ************************************************************/ |
| void cmmQmSetPrintHelp() |
| { |
| char buf[128]; |
| |
| print_all_gemac_ports(buf, 128); |
| |
| cmm_print(DEBUG_STDOUT, |
| "Usage: set qm interface {%s}\n" |
| " [reset]\n" |
| "\n" |
| " [qos]\n" |
| " [on | off]\n" |
| " [max_txdepth {bytes}]\n" |
| " [scheduler {pq|cbwfq|dwrr}] **\n" |
| " [nhigh_queue {number of queues}] **\n" |
| " [qweight {queue number} {weight}] **\n" |
| " [qdepth {queue number} {depth}] **\n" |
| "\n" |
| " [shaper {0-7}]\n" |
| " [on | off]\n" |
| " [rate {Kbps}]\n" |
| " [ifg {bytes}]\n" |
| " [bucket_size {bits}]\n" |
| " [queue {0-31}] [queue {0-31}] ...\n" |
| "\n" |
| " [scheduler {0-7}]\n" |
| " [algorithm {pq|cbwfq|dwrr}]\n" |
| " [queue {0-31}] [queue {0-31}] ...\n" |
| "\n" |
| " [queue {0-31}] [queue {0-31}] ..\n" |
| " [qos on | off] \n" |
| " [shaper {0-7}]\n" |
| " [scheduler {0-7}]\n" |
| " [qweight {weight}]\n" |
| " [qdepth {depth}]\n" |
| "\n" |
| " [rate_limiting {on|off}] **\n" |
| " [rate {Kbps}]\n" |
| " [bucket_size {bits}]\n" |
| " [queue {0-31}] [queue {0-31}] ...\n" |
| "\n" |
| " ** Deprecated\n" |
| |
| "\n" |
| #ifdef COMCERTO_2000 |
| " set qm expt_rate {eth|wifi|arp_ndp|pcap} {1000-5000000 or 0}\n" |
| #else |
| " set qm expt_rate {1000-5000000 or 0}\n" |
| #endif |
| "\n" |
| " set qm dscp_queue\n" |
| " [queue {0-31}] \n" |
| " [dscp {0-63}-{0-63}] \n", buf |
| |
| ); |
| } |
| |
| /************************************************************ |
| * |
| * |
| * |
| ************************************************************/ |
| int cmmQmSetProcess(char ** keywords, int tabStart, daemon_handle_t daemon_handle) |
| { |
| int cpt = tabStart; |
| unsigned int tmp, tmp1; |
| unsigned int cmdToSend = 0; /* bits field*/ |
| char * endptr; |
| unsigned char first_dscp = 0, last_dscp = 0, dscp_range = 0; |
| int num_dscp = 0; |
| int i; |
| unsigned char dscp_value[FPP_NUM_DSCP] = {0}; |
| |
| |
| |
| fpp_qm_qos_enable_cmd_t enableCmd; |
| fpp_qm_qos_alg_cmd_t algCmd; |
| fpp_qm_nhigh_cmd_t nHighCmd; |
| fpp_qm_max_qdepth_cmd_t maxQdepthCmd; |
| fpp_qm_max_txdepth_cmd_t maxTxDepthCmd; |
| fpp_qm_max_weight_cmd_t maxWeightCmd; |
| fpp_qm_rate_limit_cmd_t rateLimitCmd; |
| fpp_qm_expt_rate_cmd_t exptRateCmd; |
| fpp_qm_scheduler_cfg_t schedulerCmd; |
| fpp_qm_shaper_cfg_t shaperCmd; |
| fpp_qm_reset_cmd_t resetCmd; |
| fpp_qm_dscp_queue_mod_t dscpCmd; |
| fpp_qm_queue_qos_enable_cmd_t queueenableCmd; |
| |
| char rcvBuffer[256]; |
| |
| memset(&enableCmd, 0, sizeof(enableCmd)); |
| memset(&algCmd, 0, sizeof(algCmd)); |
| memset(&nHighCmd, 0, sizeof(nHighCmd)); |
| memset(&maxQdepthCmd, 0, sizeof(maxQdepthCmd)); |
| memset(&maxTxDepthCmd, 0, sizeof(maxTxDepthCmd)); |
| memset(&maxWeightCmd, 0, sizeof(maxWeightCmd)); |
| memset(&rateLimitCmd, 0, sizeof(rateLimitCmd)); |
| memset(&exptRateCmd, 0, sizeof(exptRateCmd)); |
| memset(&schedulerCmd, 0, sizeof(schedulerCmd)); |
| memset(&shaperCmd, 0, sizeof(shaperCmd)); |
| memset(&resetCmd, 0, sizeof(resetCmd)); |
| memset(&dscpCmd, 0, sizeof(dscpCmd)); |
| memset(&queueenableCmd, 0, sizeof(queueenableCmd)); |
| |
| |
| if(!keywords[cpt]) |
| goto help; |
| |
| if(strcasecmp(keywords[cpt], "interface") == 0) |
| { |
| int port_id; |
| |
| if(!keywords[++cpt]) |
| goto help; |
| |
| if ((port_id = get_port_id(keywords[cpt])) >= 0) |
| { |
| enableCmd.interface = port_id; |
| algCmd.interface = port_id; |
| nHighCmd.interface = port_id; |
| maxQdepthCmd.interface = port_id; |
| maxTxDepthCmd.interface = port_id; |
| maxWeightCmd.interface = port_id; |
| rateLimitCmd.interface = port_id; |
| shaperCmd.interface = port_id; |
| schedulerCmd.interface = port_id; |
| resetCmd.interface = port_id; |
| queueenableCmd.interface = port_id; |
| } |
| else |
| goto keyword_error; |
| } |
| else if(strcasecmp(keywords[cpt], "expt_rate") == 0) |
| { |
| if(!keywords[++cpt]) |
| goto help; |
| memset(&exptRateCmd, 0, sizeof(exptRateCmd)); |
| |
| #ifdef COMCERTO_2000 |
| if(strcasecmp(keywords[cpt], "eth") == 0 ) |
| exptRateCmd.if_type = FPP_EXPT_TYPE_ETH; |
| else if (strcasecmp(keywords[cpt], "wifi") == 0 ) |
| exptRateCmd.if_type = FPP_EXPT_TYPE_WIFI; |
| else if (strcasecmp(keywords[cpt], "arp_ndp") == 0 ) |
| exptRateCmd.if_type = FPP_EXPT_TYPE_ARP; |
| else if (strcasecmp(keywords[cpt], "pcap") == 0 ) |
| exptRateCmd.if_type = FPP_EXPT_TYPE_PCAP; |
| else |
| goto help; |
| |
| if(!keywords[++cpt]) |
| goto help; |
| #endif |
| |
| /*Get an integer from the string*/ |
| endptr = NULL; |
| tmp = strtoul(keywords[cpt], &endptr, 0); |
| if ((keywords[cpt] == endptr) || (tmp != 0 && (tmp < 1000 || tmp > 5000000))) |
| { |
| cmm_print(DEBUG_CRIT, "CMD_QM_EXPT_RATE ERROR: rate must be zero (to disable) or a number between 1000 and 5000000\n"); |
| goto help; |
| } |
| if(keywords[++cpt]) |
| goto help; |
| exptRateCmd.pkts_per_msec = tmp / 1000; |
| // Send CMD_QM_EXPT_RATE command |
| if(cmmSendToDaemon(daemon_handle, FPP_CMD_QM_EXPT_RATE, &exptRateCmd, sizeof(exptRateCmd), &rcvBuffer) == 2) |
| { |
| if ( ((unsigned short *)rcvBuffer)[0] != 0) |
| cmm_print(DEBUG_STDERR, "Error %d received from FPP for CMD_QM_EXPT_RATE\n", ((unsigned short *)rcvBuffer)[0]); |
| } |
| return 0; |
| } |
| else if(strcasecmp(keywords[cpt], "dscp_queue") == 0) |
| { |
| if(!keywords[++cpt]) |
| goto help; |
| |
| if(strcasecmp(keywords[cpt], "queue") == 0) |
| { |
| if(!keywords[++cpt]) |
| goto help; |
| |
| /*Get an integer from the string*/ |
| endptr = NULL; |
| tmp = strtoul(keywords[cpt], &endptr, 0); |
| if ((keywords[cpt] == endptr) || (tmp >= FPP_NUM_QUEUES)) |
| { |
| cmm_print(DEBUG_STDERR, "dscp_queue ERROR: selected queue must be a number between 0 and %d\n", (FPP_NUM_QUEUES-1)); |
| goto help; |
| } |
| dscpCmd.queue = tmp; |
| cmm_print(DEBUG_INFO, "dscp_queue - queue %d selected\n", dscpCmd.queue); |
| |
| if(!keywords[++cpt]) |
| goto help; |
| } |
| else |
| goto keyword_error; |
| |
| if(strcasecmp(keywords[cpt], "dscp") == 0) |
| { |
| /* get list of dscp values assigned to the selected queue */ |
| if(!keywords[++cpt]) |
| goto help; |
| num_dscp = 0; |
| first_dscp = 0; |
| cmm_print(DEBUG_INFO, "dscp_queue - parsing dscp list for queue %d\n", dscpCmd.queue); |
| while(keywords[cpt] && (num_dscp < FPP_NUM_DSCP)) |
| { |
| cmm_print(DEBUG_INFO, "dscp_queue - processing arg '%s' \n", keywords[cpt]); |
| if(strcasecmp(keywords[cpt], "-") == 0) |
| { |
| dscp_range = 1; |
| cmm_print(DEBUG_INFO, "dscp_queue - dscp range detected\n"); |
| } |
| else |
| { |
| endptr = NULL; |
| tmp = strtoul(keywords[cpt], &endptr, 0); |
| if ((keywords[cpt] == endptr) || (tmp > FPP_MAX_DSCP)) |
| { |
| cmm_print(DEBUG_STDERR, "dscp_queue ERROR: DSCP value out of range\n"); |
| goto help; |
| } |
| else |
| { |
| cmm_print(DEBUG_INFO, "dscp_queue - one more dscp added\n"); |
| /* save low-end dscp value i.e. the first value specified*/ |
| if(num_dscp == 0) |
| first_dscp = tmp; |
| last_dscp = tmp; /* save high end dscp i.e. the last one specified*/ |
| dscp_value[num_dscp++] = tmp; |
| } |
| } |
| cpt++; |
| } |
| |
| /* no dscp specified means all dscp */ |
| if(num_dscp == 0) |
| { |
| for(i = 0; i < FPP_NUM_DSCP; i++) |
| dscpCmd.dscp[i] = i; |
| dscpCmd.num_dscp = FPP_NUM_DSCP; |
| cmm_print(DEBUG_INFO, "dscp_queue - all dscp assigned\n"); |
| } |
| else if (dscp_range) |
| { |
| if(last_dscp <= first_dscp) |
| { |
| cmm_print(DEBUG_STDERR, "dscp_queue: wrong DSCP range\n"); |
| goto help; |
| } |
| for(i = first_dscp; i <= last_dscp; i++) |
| dscpCmd.dscp[i - first_dscp] = i; |
| dscpCmd.num_dscp = (last_dscp - first_dscp) + 1; |
| cmm_print(DEBUG_INFO, "dscp_queue - dscp range %d to %d\n", first_dscp, last_dscp); |
| } |
| else |
| { |
| cmm_print(DEBUG_INFO, "dscp_queue - dscp non-ordered list\n"); |
| dscpCmd.num_dscp = num_dscp; |
| for(i = 0; i < dscpCmd.num_dscp; i++) |
| dscpCmd.dscp[i] = dscp_value[i]; |
| } |
| cmm_print(DEBUG_INFO, "dscp_queue - %d dscp assigned ->\n", dscpCmd.num_dscp); |
| for(i = 0; i < dscpCmd.num_dscp; i++) |
| cmm_print(DEBUG_INFO, "%d ", dscpCmd.dscp[i]); |
| cmm_print(DEBUG_INFO, "\n"); |
| |
| if(cmmSendToDaemon(daemon_handle, FPP_CMD_QM_DSCP_MAP, &dscpCmd, sizeof(fpp_qm_dscp_queue_mod_t), rcvBuffer) == 2) |
| { |
| if ( ((unsigned short *)rcvBuffer)[0] != 0) |
| cmm_print(DEBUG_STDERR, "Error %d received from FPP for CMD_QM_DSCP_MAP\n", ((unsigned short *)rcvBuffer)[0]); |
| return ((unsigned short *)rcvBuffer)[0]; |
| } |
| } |
| else { |
| cmm_print(DEBUG_STDERR, "ERROR: Unknown keyword %s\n", keywords[cpt]); |
| goto help; |
| } |
| |
| return 0; |
| } |
| else |
| goto keyword_error; |
| |
| if(!keywords[++cpt]) |
| goto help; |
| |
| if(strcasecmp(keywords[cpt], "qos") == 0) |
| { |
| if(!keywords[++cpt]) |
| goto help; |
| |
| while (keywords[cpt] != NULL) |
| { |
| if(strcasecmp(keywords[cpt], "on") == 0) |
| { |
| cmdToSend |= CMD_BIT(FPP_CMD_QM_QOSENABLE); |
| enableCmd.enable = 1; |
| } |
| else if(strcasecmp(keywords[cpt], "off") == 0) |
| { |
| cmdToSend |= CMD_BIT(FPP_CMD_QM_QOSENABLE); |
| enableCmd.enable = 0; |
| } |
| else if(strcasecmp(keywords[cpt], "scheduler") == 0) |
| { |
| if(!keywords[++cpt]) |
| goto help; |
| |
| |
| cmdToSend |= CMD_BIT(FPP_CMD_QM_QOSALG); |
| |
| if(strcasecmp(keywords[cpt], "pq") == 0) |
| { |
| algCmd.scheduler = 0; |
| } |
| else if (strcasecmp(keywords[cpt], "cbwfq") == 0) |
| { |
| algCmd.scheduler = 1; |
| } |
| else if (strcasecmp(keywords[cpt], "dwrr") == 0) |
| { |
| algCmd.scheduler = 2; |
| } |
| else |
| goto keyword_error; |
| } |
| else if(strcasecmp(keywords[cpt], "nhigh_queue") == 0) |
| { |
| if(!keywords[++cpt]) |
| goto help; |
| |
| /*Get an integer from the string*/ |
| endptr = NULL; |
| tmp = strtoul(keywords[cpt], &endptr, 0); |
| if ((keywords[cpt] == endptr) || (tmp >= FPP_NUM_QUEUES)) |
| { |
| cmm_print(DEBUG_CRIT, "qos ERROR: nhigh_queue must be a number between 0 and %d \n", (FPP_NUM_QUEUES -1)); |
| goto help; |
| } |
| |
| nHighCmd.number_high_queues = tmp; |
| |
| cmdToSend |= CMD_BIT(FPP_CMD_QM_NHIGH); |
| } |
| else if(strcasecmp(keywords[cpt], "max_txdepth") == 0) |
| { |
| if(!keywords[++cpt]) |
| goto help; |
| |
| /*Get an integer from the string*/ |
| endptr = NULL; |
| tmp = strtoul(keywords[cpt], &endptr, 0); |
| if ((keywords[cpt] == endptr) || tmp < 1 || (tmp > USHRT_MAX)) |
| { |
| cmm_print(DEBUG_CRIT, "qos ERROR: max_txdepth must be a number between 1 and %d\n", USHRT_MAX); |
| goto help; |
| } |
| |
| maxTxDepthCmd.max_bytes = tmp; |
| |
| cmdToSend |= CMD_BIT(FPP_CMD_QM_MAX_TXDEPTH); |
| } |
| else if(strcasecmp(keywords[cpt], "qweight") == 0) |
| { |
| if(!keywords[++cpt]) |
| goto help; |
| |
| /*Get an integer from the string*/ |
| endptr = NULL; |
| tmp = strtoul(keywords[cpt], &endptr, 0); |
| if ((keywords[cpt] == endptr) || (tmp >= FPP_NUM_QUEUES)) |
| { |
| cmm_print(DEBUG_STDERR, "qos ERROR: queue must be a number between 0 and %d \n", (FPP_NUM_QUEUES -1) ); |
| goto help; |
| } |
| |
| if(!keywords[++cpt]) |
| goto help; |
| |
| /*Get an integer from the string*/ |
| endptr = NULL; |
| tmp1 = strtoul(keywords[cpt], &endptr, 0); |
| if ((keywords[cpt] == endptr) || tmp1 < 1 || (tmp1 > USHRT_MAX)) |
| { |
| cmm_print(DEBUG_STDERR, "qos ERROR: weight must be a number between 1 and %d\n", USHRT_MAX); |
| goto help; |
| } |
| |
| maxWeightCmd.qxweight[tmp] = tmp1; |
| cmdToSend |= CMD_BIT(FPP_CMD_QM_MAX_WEIGHT); |
| } |
| |
| else if(strcasecmp(keywords[cpt], "qdepth") == 0) |
| { |
| if(!keywords[++cpt]) |
| goto help; |
| |
| /*Get an integer from the string*/ |
| endptr = NULL; |
| tmp = strtoul(keywords[cpt], &endptr, 0); |
| if ((keywords[cpt] == endptr) || (tmp >= FPP_NUM_QUEUES)) |
| { |
| cmm_print(DEBUG_STDERR, "qos ERROR: queue must be a number between 0 and %d \n", (FPP_NUM_QUEUES -1)); |
| goto help; |
| } |
| |
| if(!keywords[++cpt]) |
| goto help; |
| |
| /*Get an integer from the string*/ |
| endptr = NULL; |
| tmp1 = strtoul(keywords[cpt], &endptr, 0); |
| if ((keywords[cpt] == endptr) || tmp1 < 1 || (tmp1 > USHRT_MAX)) |
| { |
| cmm_print(DEBUG_STDERR, "qos ERROR: depth must be a number between 1 and %d\n", USHRT_MAX); |
| goto help; |
| } |
| |
| maxQdepthCmd.qtxdepth[tmp] = tmp1; |
| cmdToSend |= CMD_BIT(FPP_CMD_QM_MAX_QDEPTH); |
| } |
| else |
| goto keyword_error; |
| |
| cpt++; |
| } |
| } |
| else if(strcasecmp(keywords[cpt], "rate_limiting") == 0) |
| { |
| if(!keywords[++cpt]) |
| goto help; |
| |
| if(strcasecmp(keywords[cpt], "on") == 0) |
| { |
| cmdToSend |= CMD_BIT(FPP_CMD_QM_RATE_LIMIT); |
| rateLimitCmd.enable = 1; |
| |
| cpt++; |
| while (keywords[cpt] != NULL) |
| { |
| if(strcasecmp(keywords[cpt], "queue") == 0) |
| { |
| if(!keywords[++cpt]) |
| goto help; |
| |
| /*Get an integer from the string*/ |
| endptr = NULL; |
| tmp = strtoul(keywords[cpt], &endptr, 0); |
| if ((keywords[cpt] == endptr) || (tmp >= FPP_NUM_QUEUES)) |
| { |
| cmm_print(DEBUG_CRIT, "rate_limiting ERROR: queue must be a number between 0 and %d \n", (FPP_NUM_QUEUES -1)); |
| goto help; |
| } |
| |
| rateLimitCmd.queues |= (1 << tmp); |
| } |
| else if(strcasecmp(keywords[cpt], "rate") == 0) |
| { |
| if(!keywords[++cpt]) |
| goto help; |
| |
| /*Get an integer from the string*/ |
| endptr = NULL; |
| tmp = strtoul(keywords[cpt], &endptr, 0); |
| if ((keywords[cpt] == endptr) || (tmp < 8) || (tmp > ULONG_MAX)) |
| { |
| cmm_print(DEBUG_CRIT, "rate_limiting ERROR: rate must be a number between 8 and %d (Kbps)\n", (unsigned int)ULONG_MAX); |
| goto help; |
| } |
| |
| rateLimitCmd.rate = tmp; |
| } |
| else if(strcasecmp(keywords[cpt], "bucket_size") == 0) |
| { |
| if(!keywords[++cpt]) |
| goto help; |
| |
| /*Get an integer from the string*/ |
| endptr = NULL; |
| tmp = strtoul(keywords[cpt], &endptr, 0); |
| if ((keywords[cpt] == endptr) || (tmp < 8) || (tmp > ULONG_MAX)) |
| { |
| cmm_print(DEBUG_CRIT, "rate_limiting ERROR: bucket_size must be a number between 8 and %d\n", (unsigned int)ULONG_MAX); |
| goto help; |
| } |
| |
| rateLimitCmd.bucket_size = tmp; |
| } |
| else |
| goto keyword_error; |
| |
| cpt++; |
| } |
| |
| /*Dependencies check*/ |
| if (rateLimitCmd.queues == 0) |
| { |
| cmm_print(DEBUG_CRIT, "Rate Limiting ERROR: At least one queue must be specified\n"); |
| goto help; |
| } |
| |
| if(rateLimitCmd.rate == 0) |
| { |
| cmm_print(DEBUG_CRIT, "Rate Limiting ERROR: The bandwidth have to be specified\n"); |
| goto help; |
| } |
| } |
| else if(strcasecmp(keywords[cpt], "off") == 0) |
| { |
| cmdToSend |= CMD_BIT(FPP_CMD_QM_RATE_LIMIT); |
| rateLimitCmd.enable = 0; |
| } |
| else |
| goto keyword_error; |
| |
| } |
| else if(strcasecmp(keywords[cpt], "shaper") == 0) |
| { |
| if(!keywords[++cpt]) |
| goto help; |
| |
| /*Get an integer from the string*/ |
| #ifdef COMCERTO_2000 |
| if (strcasecmp(keywords[cpt], "port") == 0) |
| { |
| tmp = FPP_PORT_SHAPER_NUM; |
| } |
| else |
| #endif |
| { |
| endptr = NULL; |
| tmp = strtoul(keywords[cpt], &endptr, 0); |
| if ((keywords[cpt] == endptr) || (tmp >= FPP_NUM_SHAPERS)) |
| { |
| cmm_print(DEBUG_CRIT, "shaper ERROR: shaper number must be between 0 and %d\n", FPP_NUM_SHAPERS); |
| goto help; |
| } |
| } |
| |
| shaperCmd.shaper = tmp; |
| |
| if(!keywords[++cpt]) |
| goto help; |
| |
| cmdToSend |= CMD_BIT(FPP_CMD_QM_SHAPER_CFG); |
| |
| while (keywords[cpt] != NULL) |
| { |
| if(strcasecmp(keywords[cpt], "on") == 0) |
| { |
| shaperCmd.enable = 1; |
| } |
| else if(strcasecmp(keywords[cpt], "off") == 0) |
| { |
| shaperCmd.enable = 2; |
| } |
| else if(strcasecmp(keywords[cpt], "queue") == 0) |
| { |
| if(!keywords[++cpt]) |
| goto help; |
| |
| /*Get an integer from the string*/ |
| endptr = NULL; |
| tmp = strtoul(keywords[cpt], &endptr, 0); |
| if ((keywords[cpt] == endptr) || (tmp >= FPP_NUM_QUEUES)) |
| { |
| cmm_print(DEBUG_CRIT, "shaper ERROR: queue must be a number between 0 and %d \n", (FPP_NUM_QUEUES -1)); |
| goto help; |
| } |
| |
| shaperCmd.queues |= (1 << tmp); |
| } |
| else if(strcasecmp(keywords[cpt], "ifg") == 0) |
| { |
| if(!keywords[++cpt]) |
| goto help; |
| |
| /*Get an integer from the string*/ |
| endptr = NULL; |
| tmp = strtoul(keywords[cpt], &endptr, 0); |
| if ((keywords[cpt] == endptr) || (tmp > 255)) |
| { |
| cmm_print(DEBUG_CRIT, "shaper ERROR: ifg must be a number between 0 and 255\n"); |
| goto help; |
| } |
| |
| shaperCmd.ifg = tmp; |
| shaperCmd.ifg_change_flag = 1; |
| } |
| else if(strcasecmp(keywords[cpt], "rate") == 0) |
| { |
| if(!keywords[++cpt]) |
| goto help; |
| |
| /* Get an integer from the string*/ |
| endptr = NULL; |
| tmp = strtoul(keywords[cpt], &endptr, 0); |
| if ((keywords[cpt] == endptr) || (tmp < 8) || (tmp > ULONG_MAX)) |
| { |
| cmm_print(DEBUG_CRIT, "shaper ERROR: rate must be a number between 8 and %d (Kbps)\n", (unsigned int)ULONG_MAX); |
| goto help; |
| } |
| |
| |
| shaperCmd.rate = tmp; |
| } |
| else if(strcasecmp(keywords[cpt], "bucket_size") == 0) |
| { |
| if(!keywords[++cpt]) |
| goto help; |
| |
| /*Get an integer from the string*/ |
| endptr = NULL; |
| tmp = strtoul(keywords[cpt], &endptr, 0); |
| if ((keywords[cpt] == endptr) || (tmp < 8) || (tmp > ULONG_MAX)) |
| { |
| cmm_print(DEBUG_CRIT, "shaper ERROR: bucket_size must be a number between 8 and %d\n", (unsigned int)ULONG_MAX); |
| goto help; |
| } |
| |
| shaperCmd.bucket_size = tmp; |
| } |
| else |
| goto keyword_error; |
| |
| cpt++; |
| } |
| } |
| else if(strcasecmp(keywords[cpt], "scheduler") == 0) |
| { |
| if(!keywords[++cpt]) |
| goto help; |
| |
| /*Get an integer from the string*/ |
| endptr = NULL; |
| tmp = strtoul(keywords[cpt], &endptr, 0); |
| if ((keywords[cpt] == endptr) || (tmp >= FPP_NUM_SCHEDULERS)) |
| { |
| cmm_print(DEBUG_CRIT, "scheduler ERROR: scheduler number must be between 0 and 3\n"); |
| goto help; |
| } |
| |
| schedulerCmd.scheduler = tmp; |
| |
| if(!keywords[++cpt]) |
| goto help; |
| |
| cmdToSend |= CMD_BIT(FPP_CMD_QM_SCHED_CFG); |
| |
| while (keywords[cpt] != NULL) |
| { |
| if(strcasecmp(keywords[cpt], "queue") == 0) |
| { |
| if(!keywords[++cpt]) |
| goto help; |
| |
| /*Get an integer from the string*/ |
| endptr = NULL; |
| tmp = strtoul(keywords[cpt], &endptr, 0); |
| if ((keywords[cpt] == endptr) || (tmp >= FPP_NUM_QUEUES)) |
| { |
| cmm_print(DEBUG_CRIT, "scheduler ERROR: queue must be a number between 0 and %d \n", (FPP_NUM_QUEUES -1)); |
| goto help; |
| } |
| |
| schedulerCmd.queues |= (1 << tmp); |
| } |
| else if(strcasecmp(keywords[cpt], "algorithm") == 0) |
| { |
| if(!keywords[++cpt]) |
| goto help; |
| |
| if(strcasecmp(keywords[cpt], "pq") == 0) |
| { |
| schedulerCmd.algo = 0; |
| schedulerCmd.algo_change_flag = 1; |
| } |
| else if (strcasecmp(keywords[cpt], "cbwfq") == 0) |
| { |
| schedulerCmd.algo = 1; |
| schedulerCmd.algo_change_flag = 1; |
| } |
| else if (strcasecmp(keywords[cpt], "dwrr") == 0) |
| { |
| schedulerCmd.algo = 2; |
| schedulerCmd.algo_change_flag = 1; |
| } |
| else |
| goto keyword_error; |
| } |
| else |
| goto keyword_error; |
| |
| cpt++; |
| } |
| |
| } |
| |
| else if(strcasecmp(keywords[cpt], "queue") == 0) |
| { |
| unsigned int qmask=0; /* Bit mask of single or set of queues that are programmed */ |
| |
| if(!keywords[++cpt]) |
| goto help; |
| |
| /*Get an integer from the string*/ |
| endptr = NULL; |
| tmp = strtoul(keywords[cpt], &endptr, 0); |
| if ((keywords[cpt] == endptr) || (tmp >= FPP_NUM_QUEUES)) |
| { |
| cmm_print(DEBUG_CRIT, "queue ERROR: queue must be a number between 0 and %d\n", (FPP_NUM_QUEUES-1)); |
| goto help; |
| } |
| qmask |= (1<<tmp); |
| |
| if(!keywords[++cpt]) |
| goto help; |
| |
| while (keywords[cpt] != NULL) |
| { |
| if(strcasecmp(keywords[cpt], "queue") == 0) |
| { |
| if(!keywords[++cpt]) |
| goto help; |
| |
| /*Get an integer from the string*/ |
| endptr = NULL; |
| tmp = strtoul(keywords[cpt], &endptr, 0); |
| if ((keywords[cpt] == endptr) || (tmp >= FPP_NUM_QUEUES)) |
| { |
| cmm_print(DEBUG_CRIT, "queue ERROR: queue must be a number between 0 and %d \n", (FPP_NUM_QUEUES -1)); |
| goto help; |
| } |
| |
| qmask |= (1<<tmp); |
| } |
| else if(strcasecmp(keywords[cpt], "qos") == 0) |
| { |
| if (qmask ==0) |
| { |
| cmm_print(DEBUG_CRIT, "queue ERROR: One or more queues need to be specified \n"); |
| goto help; |
| } |
| |
| if(!keywords[++cpt]) |
| goto help; |
| |
| |
| if(strcasecmp(keywords[cpt], "on") == 0) |
| queueenableCmd.enable_flag = 1; |
| else if(strcasecmp(keywords[cpt], "off") == 0) |
| queueenableCmd.enable_flag = 0; |
| |
| queueenableCmd.queue_qosenable_mask = qmask; |
| cmdToSend |= CMD_BIT(FPP_CMD_QM_QUEUE_QOSENABLE); |
| |
| } |
| else if(strcasecmp(keywords[cpt], "shaper") == 0) |
| { |
| if (qmask ==0) |
| { |
| cmm_print(DEBUG_CRIT, "queue ERROR: One or more queues need to be specified \n"); |
| goto help; |
| } |
| |
| if(!keywords[++cpt]) |
| goto help; |
| |
| /*Get an integer from the string*/ |
| endptr = NULL; |
| tmp = strtoul(keywords[cpt], &endptr, 0); |
| if ((keywords[cpt] == endptr) || (tmp >= FPP_NUM_SHAPERS)) |
| { |
| cmm_print(DEBUG_CRIT, "queue ERROR: shaper number must be between 0 and 4\n"); |
| goto help; |
| } |
| |
| shaperCmd.shaper = tmp; |
| shaperCmd.queues = qmask; |
| cmdToSend |= CMD_BIT(FPP_CMD_QM_SHAPER_CFG); |
| } |
| else if(strcasecmp(keywords[cpt], "scheduler") == 0) |
| { |
| if (qmask ==0) |
| { |
| cmm_print(DEBUG_CRIT, "queue ERROR: One or more queues need to be specified \n"); |
| goto help; |
| } |
| |
| if(!keywords[++cpt]) |
| goto help; |
| |
| /*Get an integer from the string*/ |
| endptr = NULL; |
| tmp = strtoul(keywords[cpt], &endptr, 0); |
| if ((keywords[cpt] == endptr) || (tmp >= FPP_NUM_SCHEDULERS)) |
| { |
| cmm_print(DEBUG_CRIT, "queue ERROR: scheduler number must be between 0 and 3\n"); |
| goto help; |
| } |
| |
| schedulerCmd.scheduler = tmp; |
| schedulerCmd.queues = qmask; |
| cmdToSend |= CMD_BIT(FPP_CMD_QM_SCHED_CFG); |
| } |
| else if(strcasecmp(keywords[cpt], "qweight") == 0) |
| { |
| if (qmask ==0) |
| { |
| cmm_print(DEBUG_CRIT, "queue ERROR: One or more queues need to be specified \n"); |
| goto help; |
| } |
| |
| if(!keywords[++cpt]) |
| goto help; |
| |
| /*Get an integer from the string*/ |
| endptr = NULL; |
| tmp1 = strtoul(keywords[cpt], &endptr, 0); |
| if ((keywords[cpt] == endptr) || tmp1 < 1 || (tmp1 > USHRT_MAX)) |
| { |
| cmm_print(DEBUG_STDERR, "queue ERROR: weight must be a number between 1 and %d\n", USHRT_MAX); |
| goto help; |
| } |
| |
| for(i=0; i < FPP_NUM_QUEUES; i++) { |
| if(qmask & (1 << i)) |
| maxWeightCmd.qxweight[i] = tmp1; |
| } |
| cmdToSend |= CMD_BIT(FPP_CMD_QM_MAX_WEIGHT); |
| } |
| |
| else if(strcasecmp(keywords[cpt], "qdepth") == 0) |
| { |
| if (qmask ==0) |
| { |
| cmm_print(DEBUG_CRIT, "queue ERROR: One or more queues need to be specified \n"); |
| goto help; |
| } |
| |
| if(!keywords[++cpt]) |
| goto help; |
| |
| /*Get an integer from the string*/ |
| endptr = NULL; |
| tmp1 = strtoul(keywords[cpt], &endptr, 0); |
| if ((keywords[cpt] == endptr) || tmp1 < 1 || (tmp1 > USHRT_MAX)) |
| { |
| cmm_print(DEBUG_STDERR, "queue ERROR: depth must be a number between 1 and %d\n", USHRT_MAX); |
| goto help; |
| } |
| |
| for(i=0; i < FPP_NUM_QUEUES; i++) { |
| if(qmask & (1 << i)) |
| maxQdepthCmd.qtxdepth[i] = tmp1; |
| } |
| cmdToSend |= CMD_BIT(FPP_CMD_QM_MAX_QDEPTH); |
| } |
| else |
| goto keyword_error; |
| |
| cpt++; |
| } |
| |
| } |
| |
| else if(strcasecmp(keywords[cpt], "reset") == 0) |
| { |
| if(keywords[++cpt]) |
| goto help; |
| |
| cmdToSend |= CMD_BIT(FPP_CMD_QM_RESET); |
| } |
| else |
| goto keyword_error; |
| |
| /* |
| * Parsing have been performed |
| * Now send the right commands |
| */ |
| |
| if(TEST_CMD_BIT(cmdToSend, FPP_CMD_QM_RESET)) |
| { |
| // Send CMD_QM_RATE_LIMIT command |
| if(cmmSendToDaemon(daemon_handle, FPP_CMD_QM_RESET, &resetCmd, sizeof(resetCmd), &rcvBuffer) == 2) |
| { |
| if ( ((unsigned short *)rcvBuffer)[0] != 0) |
| cmm_print(DEBUG_STDERR, "Error %d received from FPP for CMD_QM_RESET\n", ((unsigned short *)rcvBuffer)[0]); |
| } |
| } |
| |
| if(TEST_CMD_BIT(cmdToSend, FPP_CMD_QM_QOSENABLE)) |
| { |
| // Send CMD_QM_QOSENABLE command |
| if(cmmSendToDaemon(daemon_handle, FPP_CMD_QM_QOSENABLE, & enableCmd, sizeof(enableCmd), &rcvBuffer) == 2) |
| { |
| if ( (((unsigned short*)rcvBuffer)[0]) != 0) |
| cmm_print(DEBUG_STDERR, "Error %d received from FPP for CMD_QM_QOSENABLE\n", ((unsigned short*)rcvBuffer)[0]); |
| } |
| } |
| |
| if(TEST_CMD_BIT(cmdToSend, FPP_CMD_QM_QUEUE_QOSENABLE)) |
| { |
| // Send FPP_CMD_QM_QUEUE_QOSENABLE command |
| if(cmmSendToDaemon(daemon_handle, FPP_CMD_QM_QUEUE_QOSENABLE, &queueenableCmd, sizeof(queueenableCmd), &rcvBuffer) == 2) |
| { |
| if ( (((unsigned short*)rcvBuffer)[0]) != 0) |
| cmm_print(DEBUG_STDERR, "Error %d received from FPP for CMD_QM_QUEUE_QOSENABLE\n", ((unsigned short*)rcvBuffer)[0]); |
| } |
| } |
| |
| |
| if(TEST_CMD_BIT(cmdToSend, FPP_CMD_QM_QOSALG)) |
| { |
| // Send CMD_QM_QOSALG command |
| if(cmmSendToDaemon(daemon_handle, FPP_CMD_QM_QOSALG, & algCmd, sizeof(algCmd), &rcvBuffer) == 2) |
| { |
| if ( ((unsigned short*)rcvBuffer)[0] != 0) |
| cmm_print(DEBUG_STDERR, "Error %d received from FPP for CMD_QM_QOSALG\n", ((unsigned short*)rcvBuffer)[0]); |
| } |
| } |
| |
| if(TEST_CMD_BIT(cmdToSend, FPP_CMD_QM_NHIGH)) |
| { |
| // Send CMD_QM_NHIGH command |
| if(cmmSendToDaemon(daemon_handle, FPP_CMD_QM_NHIGH, & nHighCmd, sizeof(nHighCmd), &rcvBuffer) == 2) |
| { |
| if ( ((unsigned short*)rcvBuffer)[0] != 0) |
| cmm_print(DEBUG_STDERR, "Error %d received from FPP for CMD_QM_NHIGH\n", ((unsigned short*)rcvBuffer)[0]); |
| } |
| } |
| |
| if(TEST_CMD_BIT(cmdToSend, FPP_CMD_QM_MAX_TXDEPTH)) |
| { |
| // Send CMD_QM_MAX_TXDEPTH command |
| if(cmmSendToDaemon(daemon_handle, FPP_CMD_QM_MAX_TXDEPTH, &maxTxDepthCmd, sizeof(maxTxDepthCmd), &rcvBuffer) == 2) |
| { |
| if ( ((unsigned short*)rcvBuffer)[0] != 0) |
| cmm_print(DEBUG_STDERR, "Error %d received from FPP for CMD_QM_MAX_TXDEPTH\n", ((unsigned short*)rcvBuffer)[0]); |
| } |
| } |
| |
| if(TEST_CMD_BIT(cmdToSend, FPP_CMD_QM_MAX_QDEPTH)) |
| { |
| // Send CMD_QM_MAX_QDEPTH command |
| if(cmmSendToDaemon(daemon_handle, FPP_CMD_QM_MAX_QDEPTH, & maxQdepthCmd , sizeof(maxQdepthCmd), &rcvBuffer) == 2) |
| { |
| if ( ((unsigned short*)rcvBuffer)[0] != 0) |
| cmm_print(DEBUG_STDERR, "Error %d received from FPP for CMD_QM_MAX_QDEPTH\n", ((unsigned short*)rcvBuffer)[0]); |
| } |
| } |
| |
| if(TEST_CMD_BIT(cmdToSend, FPP_CMD_QM_MAX_WEIGHT)) |
| { |
| // Send CMD_QM_MAX_WEIGHT command |
| if(cmmSendToDaemon(daemon_handle, FPP_CMD_QM_MAX_WEIGHT, &maxWeightCmd , sizeof(maxWeightCmd), &rcvBuffer) == 2) |
| { |
| if ( ((unsigned short*)rcvBuffer)[0] != 0) |
| cmm_print(DEBUG_STDERR, "Error %d received from FPP for CMD_QM_MAX_WEIGHT\n", ((unsigned short*)rcvBuffer)[0]); |
| } |
| } |
| |
| if(TEST_CMD_BIT(cmdToSend, FPP_CMD_QM_RATE_LIMIT)) |
| { |
| // Send CMD_QM_RATE_LIMIT command |
| if(cmmSendToDaemon(daemon_handle, FPP_CMD_QM_RATE_LIMIT, &rateLimitCmd, sizeof(rateLimitCmd), &rcvBuffer) == 2) |
| { |
| if ( ((unsigned short *)rcvBuffer)[0] != 0) |
| cmm_print(DEBUG_STDERR, "Error %d received from FPP for CMD_QM_RATE_LIMIT\n", ((unsigned short *)rcvBuffer)[0]); |
| } |
| } |
| |
| if(TEST_CMD_BIT(cmdToSend, FPP_CMD_QM_SHAPER_CFG)) |
| { |
| // Send CMD_QM_RATE_LIMIT command |
| if(cmmSendToDaemon(daemon_handle, FPP_CMD_QM_SHAPER_CFG, &shaperCmd, sizeof(shaperCmd), &rcvBuffer) == 2) |
| { |
| if ( ((unsigned short *)rcvBuffer)[0] != 0) |
| cmm_print(DEBUG_STDERR, "Error %d received from FPP for CMD_QM_SHAPER_CFG\n", ((unsigned short *)rcvBuffer)[0]); |
| } |
| } |
| |
| if(TEST_CMD_BIT(cmdToSend, FPP_CMD_QM_SCHED_CFG)) |
| { |
| // Send CMD_QM_RATE_LIMIT command |
| if(cmmSendToDaemon(daemon_handle, FPP_CMD_QM_SCHED_CFG, &schedulerCmd, sizeof(schedulerCmd), &rcvBuffer) == 2) |
| { |
| if ( ((unsigned short *)rcvBuffer)[0] != 0) |
| cmm_print(DEBUG_STDERR, "Error %d received from FPP for CMD_QM_SCHED_CFG\n", ((unsigned short *)rcvBuffer)[0]); |
| } |
| } |
| |
| |
| return 0; |
| |
| keyword_error: |
| cmm_print(DEBUG_CRIT, "ERROR: Unknown keyword %s\n", keywords[cpt]); |
| |
| help: |
| cmmQmSetPrintHelp(); |
| return -1; |
| } |
| |
| |
| void cmmQmResetQ2Prio(fpp_qm_reset_cmd_t *cmdp, int cmdlen) |
| { |
| u_int16_t interface; |
| char fname[128], ifname[IFNAMSIZ]; |
| FILE *fp; |
| |
| if (cmdlen != sizeof(fpp_qm_reset_cmd_t)) |
| { |
| cmm_print(DEBUG_ERROR, "%s: Wrong length for cmd, expected %d, got %d\n", __func__, |
| sizeof(fpp_qm_scheduler_cfg_t), cmdlen); |
| return; |
| } |
| |
| interface = cmdp->interface; |
| |
| snprintf(fname, 128, "/sys/class/net/%s/q2prio", get_port_name(interface, ifname, IFNAMSIZ)); |
| fp = fopen(fname, "w"); |
| if (!fp) |
| { |
| cmm_print(DEBUG_WARNING, "%s: Cannot open %s\n", __func__, fname); |
| return; |
| } |
| fprintf(fp, "reset\n"); |
| fclose(fp); |
| } |
| |
| |
| void cmmQmUpdateQ2Prio(fpp_qm_scheduler_cfg_t *cmdp, int cmdlen) |
| { |
| u_int16_t interface; |
| u_int16_t scheduler; |
| u_int32_t queues; |
| char fname[128], ifname[IFNAMSIZ]; |
| FILE *fp; |
| |
| if (cmdlen != sizeof(fpp_qm_scheduler_cfg_t)) |
| { |
| cmm_print(DEBUG_ERROR, "%s: Wrong length for cmd, expected %d, got %d\n", __func__, |
| sizeof(fpp_qm_scheduler_cfg_t), cmdlen); |
| return; |
| } |
| |
| interface = cmdp->interface; |
| scheduler = cmdp->scheduler; |
| queues = cmdp->queues; |
| |
| snprintf(fname, 128, "/sys/class/net/%s/q2prio", get_port_name(interface, ifname, IFNAMSIZ)); |
| fp = fopen(fname, "w"); |
| if (!fp) |
| { |
| cmm_print(DEBUG_WARNING, "%s: Cannot open %s\n", __func__, fname); |
| return; |
| } |
| fprintf(fp, "%d 0x%x\n", scheduler, queues); |
| fclose(fp); |
| } |