blob: e602779b9ba6b1a58bc526562d60b3907fcee62f [file] [log] [blame]
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001/*
Girish Gowdraa707e7c2019-11-07 11:36:13 +05302 * Copyright 2018-present Open Networking Foundation
Shad Ansarib7b0ced2018-05-11 21:53:32 +00003
Girish Gowdraa707e7c2019-11-07 11:36:13 +05304 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
Shad Ansarib7b0ced2018-05-11 21:53:32 +00007
Girish Gowdraa707e7c2019-11-07 11:36:13 +05308 * http://www.apache.org/licenses/LICENSE-2.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00009
Girish Gowdraa707e7c2019-11-07 11:36:13 +053010 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +000016
17#include <iostream>
18#include <memory>
19#include <string>
20
21#include "Queue.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000022#include <sstream>
Nicolas Palpacuer9c352082018-08-14 16:37:14 -040023#include <chrono>
24#include <thread>
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080025#include <bitset>
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000026#include <inttypes.h>
Jason Huangbf45ffb2019-10-30 17:29:02 +080027#include <unistd.h>
Jason Huang09b73ea2020-01-08 17:52:05 +080028#include <sys/socket.h>
29#include <netinet/in.h>
30#include <arpa/inet.h>
Shad Ansarib7b0ced2018-05-11 21:53:32 +000031
Craig Lutgen88a22ad2018-10-04 12:30:46 -050032#include "device.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000033#include "core.h"
Girish Gowdraddf9a162020-01-27 12:56:27 +053034#include "core_data.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000035#include "indications.h"
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -040036#include "stats_collection.h"
Nicolas Palpacuer73222e02018-07-16 12:20:26 -040037#include "error_format.h"
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -040038#include "state.h"
Girish Gowdraddf9a162020-01-27 12:56:27 +053039#include "core_utils.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000040
41extern "C"
42{
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000043#include <bcmolt_api.h>
44#include <bcmolt_host_api.h>
45#include <bcmolt_api_model_supporting_enums.h>
46
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000047#include <bcmolt_api_conn_mgr.h>
48//CLI header files
49#include <bcmcli_session.h>
50#include <bcmcli.h>
51#include <bcm_api_cli.h>
52
53#include <bcmos_common.h>
54#include <bcm_config.h>
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -040055// FIXME : dependency problem
56// #include <bcm_common_gpon.h>
Nicolas Palpacuer967438f2018-09-07 14:41:54 -040057// #include <bcm_dev_log_task.h>
Shad Ansarib7b0ced2018-05-11 21:53:32 +000058}
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000059
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000060static std::string intf_technologies[MAX_SUPPORTED_PON];
Craig Lutgen88a22ad2018-10-04 12:30:46 -050061static const std::string UNKNOWN_TECH("unknown");
Craig Lutgenb2601f02018-10-23 13:04:31 -050062static const std::string MIXED_TECH("mixed");
63static std::string board_technology(UNKNOWN_TECH);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000064static std::string chip_family(UNKNOWN_TECH);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000065static std::string firmware_version = "Openolt.2019.07.01";
Nicolas Palpacuerdff96792018-09-06 14:59:32 -040066
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080067static bcmos_errno CreateSched(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
68 uint32_t port_no, uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, \
69 uint32_t priority, tech_profile::SchedulingPolicy sched_policy,
70 tech_profile::TrafficShapingInfo traffic_shaping_info);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000071static bcmos_errno RemoveSched(int intf_id, int onu_id, int uni_id, int alloc_id, std::string direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080072static bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -050073 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id);
74static bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
75 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000076static bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction);
77static bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction);
78
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000079inline const char *get_flow_acton_command(uint32_t command) {
80 char actions[200] = { };
81 char *s_actions_ptr = actions;
82 if (command & BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG) strcat(s_actions_ptr, "ADD_OUTER_TAG|");
83 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG) strcat(s_actions_ptr, "REMOVE_OUTER_TAG|");
84 if (command & BCMOLT_ACTION_CMD_ID_XLATE_OUTER_TAG) strcat(s_actions_ptr, "TRANSLATE_OUTER_TAG|");
85 if (command & BCMOLT_ACTION_CMD_ID_ADD_INNER_TAG) strcat(s_actions_ptr, "ADD_INNTER_TAG|");
86 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_INNER_TAG) strcat(s_actions_ptr, "REMOVE_INNER_TAG|");
87 if (command & BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG) strcat(s_actions_ptr, "TRANSLATE_INNER_TAG|");
88 if (command & BCMOLT_ACTION_CMD_ID_REMARK_OUTER_PBITS) strcat(s_actions_ptr, "REMOVE_OUTER_PBITS|");
89 if (command & BCMOLT_ACTION_CMD_ID_REMARK_INNER_PBITS) strcat(s_actions_ptr, "REMAKE_INNER_PBITS|");
90 return s_actions_ptr;
91}
92
Nicolas Palpacuerdff96792018-09-06 14:59:32 -040093Status GetDeviceInfo_(openolt::DeviceInfo* device_info) {
Craig Lutgen88a22ad2018-10-04 12:30:46 -050094 device_info->set_vendor(VENDOR_ID);
95 device_info->set_model(MODEL_ID);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -040096 device_info->set_hardware_version("");
97 device_info->set_firmware_version(firmware_version);
Craig Lutgenb2601f02018-10-23 13:04:31 -050098 device_info->set_technology(board_technology);
Craig Lutgen88a22ad2018-10-04 12:30:46 -050099 device_info->set_pon_ports(num_of_pon_ports);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500100
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800101 char serial_number[OPENOLT_FIELD_LEN];
102 memset(serial_number, '\0', OPENOLT_FIELD_LEN);
103 openolt_read_sysinfo("Serial Number", serial_number);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000104 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device serial number %s\n", serial_number);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800105 device_info->set_device_serial_number(serial_number);
106
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700107 char device_id[OPENOLT_FIELD_LEN];
108 memset(device_id, '\0', OPENOLT_FIELD_LEN);
109 openolt_read_sysinfo("MAC", device_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000110 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device mac address %s\n", device_id);
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700111 device_info->set_device_id(device_id);
112
Craig Lutgenb2601f02018-10-23 13:04:31 -0500113 // Legacy, device-wide ranges. To be deprecated when adapter
114 // is upgraded to support per-interface ranges
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000115 if (board_technology == "XGS-PON") {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500116 device_info->set_onu_id_start(1);
117 device_info->set_onu_id_end(255);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600118 device_info->set_alloc_id_start(MIN_ALLOC_ID_XGSPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500119 device_info->set_alloc_id_end(16383);
120 device_info->set_gemport_id_start(1024);
121 device_info->set_gemport_id_end(65535);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500122 device_info->set_flow_id_start(1);
123 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500124 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000125 else if (board_technology == "GPON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500126 device_info->set_onu_id_start(1);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500127 device_info->set_onu_id_end(127);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600128 device_info->set_alloc_id_start(MIN_ALLOC_ID_GPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500129 device_info->set_alloc_id_end(767);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500130 device_info->set_gemport_id_start(256);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500131 device_info->set_gemport_id_end(4095);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500132 device_info->set_flow_id_start(1);
133 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500134 }
Craig Lutgenb2601f02018-10-23 13:04:31 -0500135
136 std::map<std::string, openolt::DeviceInfo::DeviceResourceRanges*> ranges;
137 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
138 std::string intf_technology = intf_technologies[intf_id];
139 openolt::DeviceInfo::DeviceResourceRanges *range = ranges[intf_technology];
140 if(range == nullptr) {
141 range = device_info->add_ranges();
142 ranges[intf_technology] = range;
143 range->set_technology(intf_technology);
144
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000145 if (intf_technology == "XGS-PON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500146 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
147
148 pool = range->add_pools();
149 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
150 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
151 pool->set_start(1);
152 pool->set_end(255);
153
154 pool = range->add_pools();
155 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
156 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_SAME_TECH);
157 pool->set_start(1024);
158 pool->set_end(16383);
159
160 pool = range->add_pools();
161 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
162 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
163 pool->set_start(1024);
164 pool->set_end(65535);
165
166 pool = range->add_pools();
167 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
168 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
169 pool->set_start(1);
170 pool->set_end(16383);
171 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000172 else if (intf_technology == "GPON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500173 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
174
175 pool = range->add_pools();
176 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
177 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
178 pool->set_start(1);
179 pool->set_end(127);
180
181 pool = range->add_pools();
182 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
183 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_SAME_TECH);
184 pool->set_start(256);
185 pool->set_end(757);
186
187 pool = range->add_pools();
188 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
189 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
190 pool->set_start(256);
191 pool->set_end(4095);
192
193 pool = range->add_pools();
194 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
195 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
196 pool->set_start(1);
197 pool->set_end(16383);
198 }
199 }
200
201 range->add_intf_ids(intf_id);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500202 }
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400203
204 // FIXME: Once dependency problem is fixed
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500205 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400206 // device_info->set_onu_id_end(XGPON_NUM_OF_ONUS - 1);
207 // device_info->set_alloc_id_start(1024);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500208 // device_info->set_alloc_id_end(XGPON_NUM_OF_ALLOC_IDS * num_of_pon_ports ? - 1);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400209 // device_info->set_gemport_id_start(XGPON_MIN_BASE_SERVICE_PORT_ID);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500210 // device_info->set_gemport_id_end(XGPON_NUM_OF_GEM_PORT_IDS_PER_PON * num_of_pon_ports ? - 1);
211 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400212
213 return Status::OK;
214}
215
Shad Ansari627b5782018-08-13 22:49:32 +0000216Status Enable_(int argc, char *argv[]) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000217 bcmos_errno err;
218 bcmolt_host_init_parms init_parms = {};
219 init_parms.transport.type = BCM_HOST_API_CONN_LOCAL;
220 unsigned int failed_enable_device_cnt = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000221
Shad Ansariedef2132018-08-10 22:14:50 +0000222 if (!state.is_activated()) {
Shad Ansari627b5782018-08-13 22:49:32 +0000223
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500224 vendor_init();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000225 /* Initialize host subsystem */
226 err = bcmolt_host_init(&init_parms);
227 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500228 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to init OLT, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000229 return bcm_to_grpc_err(err, "Failed to init OLT");
230 }
231
232 bcmcli_session_parm mon_session_parm;
233 /* Create CLI session */
234 memset(&mon_session_parm, 0, sizeof(mon_session_parm));
235 mon_session_parm.get_prompt = openolt_cli_get_prompt_cb;
236 mon_session_parm.access_right = BCMCLI_ACCESS_ADMIN;
237 bcmos_errno rc = bcmcli_session_open(&mon_session_parm, &current_session);
238 BUG_ON(rc != BCM_ERR_OK);
239
240 /* API CLI */
241 bcm_openolt_api_cli_init(NULL, current_session);
242
243 /* Add quit command */
244 BCMCLI_MAKE_CMD_NOPARM(NULL, "quit", "Quit", bcm_cli_quit);
245
246 err = bcmolt_apiend_cli_init();
247 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500248 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to add apiend init, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000249 return bcm_to_grpc_err(err, "Failed to add apiend init");
250 }
251
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800252 bcmos_fastlock_init(&data_lock, 0);
Girish Gowdra96461052019-11-22 20:13:59 +0530253 bcmos_fastlock_init(&alloc_cfg_wait_lock, 0);
Girish Gowdra7a79dae2020-02-10 18:22:11 +0530254 bcmos_fastlock_init(&onu_deactivate_wait_lock, 0);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000255 OPENOLT_LOG(INFO, openolt_log_id, "Enable OLT - %s-%s\n", VENDOR_ID, MODEL_ID);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600256
Jason Huangbf45ffb2019-10-30 17:29:02 +0800257 //check BCM daemon is connected or not
258 Status status = check_connection();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000259 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800260 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000261 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800262 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000263 Status status = SubscribeIndication();
264 if (!status.ok()) {
265 OPENOLT_LOG(ERROR, openolt_log_id, "SubscribeIndication failed - %s : %s\n",
266 grpc_status_code_to_string(status.error_code()).c_str(),
267 status.error_message().c_str());
268 return status;
269 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800270
271 //check BAL state in initial stage
272 status = check_bal_ready();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000273 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800274 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000275 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800276 }
277
278 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000279 bcmos_errno err;
280 bcmolt_odid dev;
281 OPENOLT_LOG(INFO, openolt_log_id, "Enabling PON %d Devices ... \n", BCM_MAX_DEVS_PER_LINE_CARD);
282 for (dev = 0; dev < BCM_MAX_DEVS_PER_LINE_CARD; dev++) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400283 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000284 bcmolt_device_key dev_key = { };
285 dev_key.device_id = dev;
286 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
287 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
288 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
Jason Huangbf45ffb2019-10-30 17:29:02 +0800289 if (err == BCM_ERR_NOT_CONNECTED) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000290 bcmolt_device_key key = {.device_id = dev};
291 bcmolt_device_connect oper;
292 BCMOLT_OPER_INIT(&oper, device, connect, key);
293 if (MODEL_ID == "asfvolt16") {
294 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
295 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_XGS__2_X);
296 } else if (MODEL_ID == "asgvolt64") {
297 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
298 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
299 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
300 }
301 err = bcmolt_oper_submit(dev_id, &oper.hdr);
302 if (err) {
303 failed_enable_device_cnt ++;
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500304 OPENOLT_LOG(ERROR, openolt_log_id, "Enable PON device %d failed, err = %s\n", dev, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000305 if (failed_enable_device_cnt == BCM_MAX_DEVS_PER_LINE_CARD) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500306 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to enable all the pon ports, err = %s\n", bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000307 return Status(grpc::StatusCode::INTERNAL, "Failed to activate all PON ports");
308 }
309 }
310 bcmos_usleep(200000);
311 }
312 else {
313 OPENOLT_LOG(WARNING, openolt_log_id, "PON deivce %d already connected\n", dev);
314 state.activate();
315 }
316 }
317 init_stats();
Shad Ansari627b5782018-08-13 22:49:32 +0000318 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000319 }
Shad Ansariedef2132018-08-10 22:14:50 +0000320
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000321 /* Start CLI */
322 OPENOLT_LOG(INFO, def_log_id, "Starting CLI\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400323 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000324 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400325}
326
327Status Disable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400328 //In the earlier implementation Disabling olt is done by disabling the NNI port associated with that.
329 //In inband scenario instead of using management interface to establish connection with adapter ,NNI interface will be used.
330 //Disabling NNI port on olt disable causes connection loss between adapter and agent.
331 //To overcome this disable is implemented by disabling all the PON ports
332 //associated with the device so as to support both in-band
333 //and out of band scenarios.
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400334
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400335 Status status;
336 int failedCount = 0;
337 for (int i = 0; i < NumPonIf_(); i++) {
338 status = DisablePonIf_(i);
339 if (!status.ok()) {
340 failedCount+=1;
341 BCM_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", i);
342 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400343 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400344 if (failedCount == 0) {
345 state.deactivate();
346 openolt::Indication ind;
347 openolt::OltIndication* olt_ind = new openolt::OltIndication;
348 olt_ind->set_oper_state("down");
349 ind.set_allocated_olt_ind(olt_ind);
350 BCM_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
351 oltIndQ.push(ind);
352 return Status::OK;
353 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000354 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400355 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to disable olt ,all the PON ports are still in enabled state");
356 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400357
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400358 return grpc::Status(grpc::StatusCode::UNKNOWN, "failed to disable olt ,few PON ports are still in enabled state");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400359}
360
361Status Reenable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400362 Status status;
363 int failedCount = 0;
364 for (int i = 0; i < NumPonIf_(); i++) {
365 status = EnablePonIf_(i);
366 if (!status.ok()) {
367 failedCount+=1;
368 BCM_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", i);
369 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400370 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000371 if (failedCount == 0) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400372 state.activate();
373 openolt::Indication ind;
374 openolt::OltIndication* olt_ind = new openolt::OltIndication;
375 olt_ind->set_oper_state("up");
376 ind.set_allocated_olt_ind(olt_ind);
377 BCM_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
378 oltIndQ.push(ind);
379 return Status::OK;
380 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000381 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400382 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to re-enable olt ,all the PON ports are still in disabled state");
383 }
384 return grpc::Status(grpc::StatusCode::UNKNOWN, "failed to re-enable olt ,few PON ports are still in disabled state");
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000385}
386
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000387inline uint64_t get_flow_status(uint16_t flow_id, uint16_t flow_type, uint16_t data_id) {
388 bcmos_errno err;
389 bcmolt_flow_key flow_key;
390 bcmolt_flow_cfg flow_cfg;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400391
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000392 flow_key.flow_id = flow_id;
393 flow_key.flow_type = (bcmolt_flow_type)flow_type;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400394
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000395 BCMOLT_CFG_INIT(&flow_cfg, flow, flow_key);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400396
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000397 switch (data_id) {
398 case ONU_ID: //onu_id
399 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, onu_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500400 #ifdef TEST_MODE
401 // It is impossible to mock the setting of flow_cfg.data.state because
402 // the actual bcmolt_cfg_get passes the address of flow_cfg.hdr and we cannot
403 // set the flow_cfg.data. So a new stub function is created and address
404 // of flow_cfg is passed. This is one-of case where we need to add test specific
405 // code in production code.
406 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
407 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000408 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500409 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000410 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500411 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get onu_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000412 return err;
413 }
414 return flow_cfg.data.onu_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400415 case FLOW_TYPE:
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500416 #ifdef TEST_MODE
417 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
418 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000419 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500420 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000421 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500422 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get flow_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000423 return err;
424 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400425 return flow_cfg.key.flow_type;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000426 case SVC_PORT_ID: //svc_port_id
427 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, svc_port_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500428 #ifdef TEST_MODE
429 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
430 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000431 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500432 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000433 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500434 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get svc_port_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000435 return err;
436 }
437 return flow_cfg.data.svc_port_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400438 case PRIORITY:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000439 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, priority);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500440 #ifdef TEST_MODE
441 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
442 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000443 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500444 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000445 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500446 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get priority, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000447 return err;
448 }
449 return flow_cfg.data.priority;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400450 case COOKIE: //cookie
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000451 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, cookie);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500452 #ifdef TEST_MODE
453 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
454 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000455 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500456 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000457 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500458 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get cookie, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000459 return err;
460 }
461 return flow_cfg.data.cookie;
462 case INGRESS_INTF_TYPE: //ingress intf_type
463 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500464 #ifdef TEST_MODE
465 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
466 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000467 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500468 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000469 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500470 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get ingress intf_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000471 return err;
472 }
473 return flow_cfg.data.ingress_intf.intf_type;
474 case EGRESS_INTF_TYPE: //egress intf_type
475 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500476 #ifdef TEST_MODE
477 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
478 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000479 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500480 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000481 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500482 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress intf_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000483 return err;
484 }
485 return flow_cfg.data.egress_intf.intf_type;
486 case INGRESS_INTF_ID: //ingress intf_id
487 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500488 #ifdef TEST_MODE
489 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
490 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000491 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500492 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000493 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500494 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get ingress intf_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000495 return err;
496 }
497 return flow_cfg.data.ingress_intf.intf_id;
498 case EGRESS_INTF_ID: //egress intf_id
499 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500500 #ifdef TEST_MODE
501 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
502 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000503 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500504 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000505 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500506 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress intf_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000507 return err;
508 }
509 return flow_cfg.data.egress_intf.intf_id;
510 case CLASSIFIER_O_VID:
511 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500512 #ifdef TEST_MODE
513 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
514 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000515 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500516 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000517 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500518 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier o_vid, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000519 return err;
520 }
521 return flow_cfg.data.classifier.o_vid;
522 case CLASSIFIER_O_PBITS:
523 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500524 #ifdef TEST_MODE
525 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
526 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000527 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500528 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000529 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500530 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier o_pbits, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000531 return err;
532 }
533 return flow_cfg.data.classifier.o_pbits;
534 case CLASSIFIER_I_VID:
535 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500536 #ifdef TEST_MODE
537 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
538 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000539 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500540 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000541 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500542 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier i_vid, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000543 return err;
544 }
545 return flow_cfg.data.classifier.i_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400546 case CLASSIFIER_I_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000547 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500548 #ifdef TEST_MODE
549 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
550 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000551 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500552 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000553 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500554 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier i_pbits, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000555 return err;
556 }
557 return flow_cfg.data.classifier.i_pbits;
558 case CLASSIFIER_ETHER_TYPE:
559 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500560 #ifdef TEST_MODE
561 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
562 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000563 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500564 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000565 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500566 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier ether_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000567 return err;
568 }
569 return flow_cfg.data.classifier.ether_type;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400570 case CLASSIFIER_IP_PROTO:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000571 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500572 #ifdef TEST_MODE
573 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
574 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000575 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500576 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000577 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500578 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier ip_proto, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000579 return err;
580 }
581 return flow_cfg.data.classifier.ip_proto;
582 case CLASSIFIER_SRC_PORT:
583 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500584 #ifdef TEST_MODE
585 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
586 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000587 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500588 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000589 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500590 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier src_port, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000591 return err;
592 }
593 return flow_cfg.data.classifier.src_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400594 case CLASSIFIER_DST_PORT:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000595 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500596 #ifdef TEST_MODE
597 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
598 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000599 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500600 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000601 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500602 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier dst_port, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000603 return err;
604 }
605 return flow_cfg.data.classifier.dst_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400606 case CLASSIFIER_PKT_TAG_TYPE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000607 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500608 #ifdef TEST_MODE
609 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
610 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000611 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500612 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000613 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500614 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier pkt_tag_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000615 return err;
616 }
617 return flow_cfg.data.classifier.pkt_tag_type;
618 case EGRESS_QOS_TYPE:
619 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500620 #ifdef TEST_MODE
621 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
622 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000623 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500624 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000625 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500626 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000627 return err;
628 }
629 return flow_cfg.data.egress_qos.type;
630 case EGRESS_QOS_QUEUE_ID:
631 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500632 #ifdef TEST_MODE
633 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
634 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000635 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500636 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000637 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500638 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos queue_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000639 return err;
640 }
641 switch (flow_cfg.data.egress_qos.type) {
642 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE:
643 return flow_cfg.data.egress_qos.u.fixed_queue.queue_id;
644 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE:
645 return flow_cfg.data.egress_qos.u.tc_to_queue.tc_to_queue_id;
646 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC:
647 return flow_cfg.data.egress_qos.u.pbit_to_tc.tc_to_queue_id;
648 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE:
649 return flow_cfg.data.egress_qos.u.priority_to_queue.tm_q_set_id;
650 case BCMOLT_EGRESS_QOS_TYPE_NONE:
651 default:
652 return -1;
653 }
654 case EGRESS_QOS_TM_SCHED_ID:
655 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500656 #ifdef TEST_MODE
657 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
658 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000659 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500660 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000661 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500662 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos tm_sched_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000663 return err;
664 }
665 return flow_cfg.data.egress_qos.tm_sched.id;
666 case ACTION_CMDS_BITMASK:
667 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500668 #ifdef TEST_MODE
669 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
670 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000671 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500672 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000673 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500674 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action cmds_bitmask, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000675 return err;
676 }
677 return flow_cfg.data.action.cmds_bitmask;
678 case ACTION_O_VID:
679 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500680 #ifdef TEST_MODE
681 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
682 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000683 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500684 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000685 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500686 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action o_vid, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000687 return err;
688 }
689 return flow_cfg.data.action.o_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400690 case ACTION_O_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000691 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500692 #ifdef TEST_MODE
693 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
694 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000695 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500696 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000697 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500698 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action o_pbits, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000699 return err;
700 }
701 return flow_cfg.data.action.o_pbits;
702 case ACTION_I_VID:
703 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500704 #ifdef TEST_MODE
705 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
706 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000707 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500708 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000709 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500710 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action i_vid, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000711 return err;
712 }
713 return flow_cfg.data.action.i_vid;
714 case ACTION_I_PBITS:
715 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500716 #ifdef TEST_MODE
717 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
718 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000719 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500720 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000721 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500722 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action i_pbits, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000723 return err;
724 }
725 return flow_cfg.data.action.i_pbits;
726 case STATE:
727 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, state);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500728 #ifdef TEST_MODE
729 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
730 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000731 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500732 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000733 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500734 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get state, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000735 return err;
736 }
737 return flow_cfg.data.state;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000738 case GROUP_ID:
739 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, group_id);
740 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
741 if (err) {
742 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get group_id, err = %s\n",bcmos_strerror(err));
743 return err;
744 }
745 return flow_cfg.data.group_id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000746 default:
747 return BCM_ERR_INTERNAL;
748 }
749
750 return err;
751}
752
753Status EnablePonIf_(uint32_t intf_id) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400754 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000755 bcmolt_pon_interface_cfg interface_obj;
756 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
757 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
758 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530759 bcmolt_status los_status;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000760
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530761 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000762 if (err == BCM_ERR_OK) {
763 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800764 OPENOLT_LOG(WARNING, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000765 return Status::OK;
766 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400767 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000768 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
769 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
770 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
771 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.interval, 5000);
772 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.onu_post_discovery_mode,
773 BCMOLT_ONU_POST_DISCOVERY_MODE_ACTIVATE);
774 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.los, true);
775 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.onu_alarms, true);
776 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.tiwi, true);
777 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.ack_timeout, true);
778 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.sfi, true);
779 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.loki, true);
780 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
781 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
782
783 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
784 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500785 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to enable discovery onu, PON interface %d, err = %s\n", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000786 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
787 }
788 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
789 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500790 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d, err = %s\n", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000791 return bcm_to_grpc_err(err, "Failed to enable PON interface");
792 }
793 else {
794 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
795 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
796 CreateDefaultSched(intf_id, downstream);
797 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400798 }
799
800 return Status::OK;
801}
802
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500803Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000804 bcmos_errno err;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400805 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000806 bcmolt_device_key dev_key = { };
807 bcmolt_olt_cfg olt_cfg = { };
808 bcmolt_olt_key olt_key = { };
809 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
810 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500811
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000812 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
813 topo.topology_maps.arr = &topo_map[0];
814 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
815 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
816 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400817 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000818 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400819 #ifdef TEST_MODE
820 // It is impossible to mock the setting of olt_cfg.data.bal_state because
821 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
822 // set the olt_cfg.data.topology. So a new stub function is created and address
823 // of olt_cfg is passed. This is one-of case where we need to test add specific
824 // code in production code.
825 err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
826 #else
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000827 err = bcmolt_cfg_get_mult_retry(dev_id, &olt_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400828 #endif
829 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500830 OPENOLT_LOG(ERROR, openolt_log_id, "cfg: Failed to query OLT topology, err = %s\n", bcmos_strerror(err));
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000831 return bcm_to_grpc_err(err, "cfg: Failed to query OLT topology");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500832 }
833
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000834 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
835 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500836
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400837 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
838 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000839 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500840
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000841 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
842 num_of_nni_ports,
843 num_of_pon_ports,
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400844 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500845
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000846 uint32_t num_failed_cfg_gets = 0;
Jason Huang09b73ea2020-01-08 17:52:05 +0800847 static std::string openolt_version = firmware_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000848 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
849 dev_key.device_id = devid;
850 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
851 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
852 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
853 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000854 err = bcmolt_cfg_get_mult_retry(dev_id, &dev_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400855 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500856 OPENOLT_LOG(WARNING, openolt_log_id,"Failed to query PON MAC Device %d (errno = %s). Skipping the device.\n", devid, bcmos_strerror(err));
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000857 num_failed_cfg_gets++;
858 continue;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000859 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500860
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000861 std::string bal_version;
862 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
863 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
864 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
Jason Huang09b73ea2020-01-08 17:52:05 +0800865 firmware_version = "BAL." + bal_version + "__" + openolt_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000866
867 switch(dev_cfg.data.system_mode) {
868 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
869 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
870 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
871 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
872 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
873 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
874 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
875 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
876 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
877 case 20: board_technology = MIXED_TECH; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,MIXED_TECH); break;
878 }
879
880 switch(dev_cfg.data.chip_family) {
Jason Huang09b73ea2020-01-08 17:52:05 +0800881 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X: chip_family = "Maple"; break;
882 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X: chip_family = "Aspen"; break;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000883 }
884
Jason Huang09b73ea2020-01-08 17:52:05 +0800885 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s, family: %s, board_technology: %s\n",
886 devid, BCM_MAX_PONS_PER_DEV, bal_version.c_str(), chip_family.c_str(), board_technology.c_str());
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000887
888 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500889 }
890
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000891 /* If all the devices returned errors then we tell the caller that this is an error else we work with
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000892 only the devices that retured success*/
893 if (num_failed_cfg_gets == BCM_MAX_DEVS_PER_LINE_CARD) {
894 OPENOLT_LOG(ERROR, openolt_log_id, "device: Query of all the devices failed\n");
895 return bcm_to_grpc_err(err, "device: All devices failed query");
896 }
897
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500898 return Status::OK;
899}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400900
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000901Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000902 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000903 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
904 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
905 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -0500906
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400907 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000908 if (err == BCM_ERR_OK) {
909 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800910 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000911 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
912 CreateDefaultSched(intf_id, upstream);
913 CreateDefaultQueue(intf_id, upstream);
914 return Status::OK;
915 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
916 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
917 return Status::OK;
918 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -0500919 }
920
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000921 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
922 if (set_state) {
923 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
924 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
925 } else {
926 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
927 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
928 }
929 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
930 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500931 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err = %s\n",
932 (set_state)?"enable":"disable", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000933 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
934 }
935 else {
936 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
937 if (set_state) {
938 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
939 CreateDefaultSched(intf_id, upstream);
940 CreateDefaultQueue(intf_id, upstream);
941 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400942 }
943
944 return Status::OK;
945}
946
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -0400947Status DisablePonIf_(uint32_t intf_id) {
Chaitrashree G S73e084d2019-11-20 16:18:59 -0500948 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000949 bcmolt_pon_interface_cfg interface_obj;
Chaitrashree G S73e084d2019-11-20 16:18:59 -0500950 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
951 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -0400952
Chaitrashree G S73e084d2019-11-20 16:18:59 -0500953 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
954 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
955 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_DISABLE);
956
957 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
958 if (err != BCM_ERR_OK) {
959 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable discovery of onu, PON interface %d, err %d\n", intf_id, err);
960 return bcm_to_grpc_err(err, "Failed to disable discovery of onu");
961 }
962
963 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
964 operation, BCMOLT_INTERFACE_OPERATION_INACTIVE);
965
966 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
967 if (err != BCM_ERR_OK) {
968 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n , err %d\n", intf_id, err);
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400969 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -0400970 }
971
Chaitrashree G S73e084d2019-11-20 16:18:59 -0500972 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled PON interface: %d\n", intf_id);
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -0400973 return Status::OK;
974}
975
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000976Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700977 const char *vendor_id, const char *vendor_specific, uint32_t pir) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000978 bcmos_errno err = BCM_ERR_OK;
979 bcmolt_onu_cfg onu_cfg;
980 bcmolt_onu_key onu_key;
981 bcmolt_serial_number serial_number; /**< ONU serial number */
982 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000983
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000984 onu_key.onu_id = onu_id;
985 onu_key.pon_ni = intf_id;
986 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
987 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -0500988 #ifdef TEST_MODE
989 // It is impossible to mock the setting of onu_cfg.data.onu_state because
990 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
991 // set the onu_cfg.data.onu_state. So a new stub function is created and address
992 // of onu_cfg is passed. This is one-of case where we need to add test specific
993 // code in production code.
994 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
995 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000996 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -0500997 #endif
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400998 if (err == BCM_ERR_OK) {
999 if ((onu_cfg.data.onu_state == BCMOLT_ONU_STATE_PROCESSING ||
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001000 onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) ||
1001 (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_INACTIVE &&
1002 onu_cfg.data.onu_old_state == BCMOLT_ONU_STATE_NOT_CONFIGURED))
1003 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001004 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001005
1006 OPENOLT_LOG(INFO, openolt_log_id, "Enabling ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001007vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001008 vendor_specific_to_str(vendor_specific).c_str(), pir);
1009
1010 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1011 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1012 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1013 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1014 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1015 /*set burst and data profiles to fec disabled*/
1016 if (board_technology == "XGS-PON") {
1017 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1018 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1019 } else if (board_technology == "GPON") {
1020 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1021 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1022 }
1023 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1024 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001025 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to set activate ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001026 return bcm_to_grpc_err(err, "Failed to activate ONU");
1027 }
1028
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001029 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001030}
1031
Jonathan Davis70c21812018-07-19 15:32:10 -04001032Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1033 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001034 bcmos_errno err = BCM_ERR_OK;
1035 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1036 bcmolt_onu_cfg onu_cfg;
1037 bcmolt_onu_key onu_key; /**< Object key. */
1038 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001039
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001040 onu_key.onu_id = onu_id;
1041 onu_key.pon_ni = intf_id;
1042 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1043 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001044 #ifdef TEST_MODE
1045 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1046 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1047 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1048 // of onu_cfg is passed. This is one-of case where we need to add test specific
1049 // code in production code.
1050 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001051 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001052 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001053 #endif
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301054 onu_state = onu_cfg.data.onu_state;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001055 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001056 switch (onu_state) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001057 case BCMOLT_ONU_STATE_ACTIVE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001058 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001059 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001060 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1061 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1062 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001063 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to deactivate ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001064 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1065 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301066 OPENOLT_LOG(INFO, openolt_log_id, "Deactivated ONU, onu_id %d on PON %d\n", onu_id, intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001067 break;
1068 }
Jonathan Davis70c21812018-07-19 15:32:10 -04001069 }
1070
1071 return Status::OK;
1072}
1073
1074Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001075 const char *vendor_id, const char *vendor_specific) {
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301076 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301077 bcmolt_onu_state onu_state;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001078
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001079 OPENOLT_LOG(INFO, openolt_log_id, "DeleteOnu ONU %d on PON %d : vendor id %s, vendor specific %s\n",
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001080 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1081
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001082 // Need to deactivate before removing it (BAL rules)
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001083 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301084
1085 err = get_onu_status((bcmolt_interface)intf_id, onu_id, &onu_state);
1086 if (err == BCM_ERR_OK) {
1087 if (onu_state == BCMOLT_ONU_STATE_ACTIVE) {
1088 OPENOLT_LOG(INFO, openolt_log_id, "Onu is Active, onu_id: %d, waiting for onu deactivate complete response\n",
1089 intf_id);
1090 err = wait_for_onu_deactivate_complete(intf_id, onu_id);
1091 if (err) {
1092 OPENOLT_LOG(ERROR, openolt_log_id, "failed to delete onu intf_id %d, onu_id %d\n",
1093 intf_id, onu_id);
1094 return bcm_to_grpc_err(err, "Failed to delete ONU");
1095 }
1096 }
1097 else if (onu_state == BCMOLT_ONU_STATE_INACTIVE) {
1098 OPENOLT_LOG(INFO, openolt_log_id, "Onu is Inactive, onu_id: %d, not waiting for onu deactivate complete response\n",
1099 intf_id);
1100 }
1101 }
1102 else {
1103 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch Onu status, onu_id = %d, intf_id = %d, err = %s\n",
1104 onu_id, intf_id, bcmos_strerror(err));
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301105 return bcm_to_grpc_err(err, "Failed to delete ONU");
1106 }
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001107
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001108 bcmolt_onu_cfg cfg_obj;
1109 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001110
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001111 OPENOLT_LOG(INFO, openolt_log_id, "Processing onu cfg clear for onu_id %d and intf_id %d\n",
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001112 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001113
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001114 key.onu_id = onu_id;
1115 key.pon_ni = intf_id;
1116 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001117
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301118 err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001119 if (err != BCM_ERR_OK)
1120 {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001121 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to clear information for BAL onu_id %d, Interface ID %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
Jonathan Davis70c21812018-07-19 15:32:10 -04001122 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1123 }
1124
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301125 OPENOLT_LOG(INFO, openolt_log_id, "Deleted ONU, onu_id %d on PON %d\n", onu_id, intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001126 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001127}
1128
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001129#define MAX_CHAR_LENGTH 20
1130#define MAX_OMCI_MSG_LENGTH 44
1131Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001132 bcmolt_bin_str buf = {};
1133 bcmolt_onu_cpu_packets omci_cpu_packets;
1134 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001135
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001136 key.pon_ni = intf_id;
1137 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001138
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001139 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1140 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1141 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001142
1143 // ???
1144 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1145 buf.len = MAX_OMCI_MSG_LENGTH;
1146 } else {
1147 buf.len = pkt.size()/2;
1148 }
1149
1150 /* Send the OMCI packet using the BAL remote proxy API */
1151 uint16_t idx1 = 0;
1152 uint16_t idx2 = 0;
1153 uint8_t arraySend[buf.len];
1154 char str1[MAX_CHAR_LENGTH];
1155 char str2[MAX_CHAR_LENGTH];
1156 memset(&arraySend, 0, buf.len);
1157
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001158 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1159 sprintf(str1,"%c", pkt[idx1]);
1160 sprintf(str2,"%c", pkt[++idx1]);
1161 strcat(str1,str2);
1162 arraySend[idx2] = strtol(str1, NULL, 16);
1163 }
1164
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001165 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1166 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001167
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001168 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1169 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1170 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001171
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001172 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001173 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001174 OPENOLT_LOG(ERROR, openolt_log_id, "Error sending OMCI message to ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001175 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001176 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001177 OPENOLT_LOG(DEBUG, omci_log_id, "OMCI request msg of length %d sent to ONU %d on PON %d : %s\n",
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001178 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001179 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001180 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001181
1182 return Status::OK;
1183}
1184
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001185Status OnuPacketOut_(uint32_t intf_id, uint32_t onu_id, uint32_t port_no, uint32_t gemport_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001186 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1187 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1188 bcmolt_bin_str buf = {};
1189 bcmolt_gem_port_id gem_port_id_array[1];
1190 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001191
Craig Lutgen967a1d02018-11-27 10:41:51 -06001192 if (port_no > 0) {
1193 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001194 if (gemport_id == 0) {
1195 bcmos_fastlock_lock(&data_lock);
1196 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1197 // Pick any flow that is mapped with the same port_no.
1198 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1199 if (it != port_to_flows.end() && !it->second.empty()) {
1200 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1201 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1202 if (fit != flowid_to_gemport.end()) {
1203 found = true;
1204 gemport_id = fit->second;
1205 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001206 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001207 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001208
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001209 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001210 OPENOLT_LOG(ERROR, openolt_log_id, "Packet out failed to find destination for ONU %d port_no %u on PON %d\n",
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001211 onu_id, port_no, intf_id);
1212 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1213 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001214 OPENOLT_LOG(INFO, openolt_log_id, "Gem port %u found for ONU %d port_no %u on PON %d\n",
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001215 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001216 }
1217
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001218 gem_port_id_array[0] = gemport_id;
1219 gem_port_list.len = 1;
1220 gem_port_list.arr = gem_port_id_array;
1221 buf.len = pkt.size();
1222 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1223 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1224
1225 /* init the API struct */
1226 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1227 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1228 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1229 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1230 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1231
1232 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1233 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1234
1235 /* call API */
1236 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001237 }
1238 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001239 //TODO: Port No is 0, it is coming sender requirement.
1240 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1241 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001242 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001243 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001244
1245 return Status::OK;
1246}
1247
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001248Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001249 bcmolt_flow_key key = {}; /* declare key */
1250 bcmolt_bin_str buffer = {};
1251 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001252
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001253 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
1254 bcmolt_flow_id flow_id = 0;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001255
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001256 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1257 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1258 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1259 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1260 key.flow_id = flow_id;
1261 else {
Jason Huang09b73ea2020-01-08 17:52:05 +08001262 if (flow_id_counters) {
1263 std::map<flow_pair, int>::iterator it;
1264 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1265 int flow_index = it->first.first;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001266 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1267 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1268 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1269 key.flow_id = flow_index;
1270 break;
1271 }
1272 }
1273 }
1274 else {
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001275 OPENOLT_LOG(ERROR, openolt_log_id, "no flow id found for uplink packetout\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001276 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1277 }
1278 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001279
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001280 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001281
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001282 /* Initialize the API struct. */
1283 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001284
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001285 buffer.len = pkt.size();
1286 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1287 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1288 if (buffer.arr == NULL) {
1289 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1290 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1291 }
1292 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1293
1294 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1295 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001296 OPENOLT_LOG(ERROR, openolt_log_id, "Error sending packets via nni port %d, flow_id %d, err = %s\n", intf_id, key.flow_id, bcmos_strerror(err));
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001297 return bcm_to_grpc_err(BCM_ERR_SYSCALL_ERR, "Error sending packets via nni port");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001298 } else {
1299 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1300 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001301
1302 return Status::OK;
1303}
Craig Lutgen967a1d02018-11-27 10:41:51 -06001304Status FlowAdd_(int32_t access_intf_id, int32_t onu_id, int32_t uni_id, uint32_t port_no,
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001305 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001306 int32_t alloc_id, int32_t network_intf_id,
1307 int32_t gemport_id, const ::openolt::Classifier& classifier,
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001308 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie,
1309 int32_t group_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001310 bcmolt_flow_cfg cfg;
1311 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001312 int32_t o_vid = -1;
1313 bool single_tag = false;
1314 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001315 bcmolt_classifier c_val = { };
1316 bcmolt_action a_val = { };
1317 bcmolt_tm_queue_ref tm_val = { };
1318 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05001319 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001320
Jason Huang09b73ea2020-01-08 17:52:05 +08001321 OPENOLT_LOG(INFO, openolt_log_id, "flow add received for flow_id=%u, flow_type=%s\n", flow_id, flow_type.c_str());
1322
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001323 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001324 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001325 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001326 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001327 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001328 } else if (flow_type.compare(multicast) == 0) {
1329 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001330 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001331 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001332 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001333 }
1334
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001335 BCMOLT_CFG_INIT(&cfg, flow, key);
1336 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001337
Jason Huang09b73ea2020-01-08 17:52:05 +08001338 if (action.cmd().trap_to_host()) {
1339 Status resp = handle_acl_rule_install(onu_id, flow_id, flow_type, access_intf_id,
1340 network_intf_id, gemport_id, classifier);
1341 return resp;
1342 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001343
1344 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1345
1346 if (access_intf_id >= 0 && network_intf_id >= 0) {
1347 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1348 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1349 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08001350 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1351 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001352 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1353 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1354 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1355 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1356 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001357 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001358 } else {
1359 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
1360 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001361 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001362
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001363 if (onu_id >= 0) {
1364 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
1365 }
1366 if (gemport_id >= 0) {
1367 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
1368 }
1369 if (gemport_id >= 0 && port_no != 0) {
1370 bcmos_fastlock_lock(&data_lock);
1371 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
1372 port_to_flows[port_no].insert(key.flow_id);
1373 flowid_to_gemport[key.flow_id] = gemport_id;
1374 }
1375 else
1376 {
1377 flowid_to_port[key.flow_id] = port_no;
1378 }
1379 bcmos_fastlock_unlock(&data_lock, 0);
1380 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001381 if (gemport_id >= 0 && access_intf_id >= 0) {
1382 // Update the flow_to_acl_map. Note that since this is a datapath flow, acl_id is -1
1383 // This info is needed during flow remove where we need to retrieve the gemport_id
1384 // and access_intf id for the given flow id and flow direction.
1385 // After retrieving the ACL ID and GEM PORT ID, we decrement the corresponding
1386 // reference counters for those ACL ID and GEMPORT ID.
1387 acl_id_gem_id_intf_id ac_id_gm_id_if_id(-1, gemport_id, access_intf_id);
1388 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
1389 bcmos_fastlock_lock(&data_lock);
1390 flow_to_acl_map[fl_id_fl_dir] = ac_id_gm_id_if_id;
1391 bcmos_fastlock_unlock(&data_lock, 0);
1392 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001393 if (priority_value >= 0) {
1394 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
1395 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301396
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001397 } else { // MULTICAST FLOW
1398 if (group_id >= 0) {
1399 BCMOLT_MSG_FIELD_SET(&cfg, group_id, group_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001400 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001401 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1402 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001403 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001404
1405 {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001406 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001407 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001408 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
1409 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001410 }
1411
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001412 if (classifier.dst_mac().size() > 0) {
1413 bcmos_mac_address d_mac = {};
1414 bcmos_mac_address_init(&d_mac);
1415 memcpy(d_mac.u8, classifier.dst_mac().data(), sizeof(d_mac.u8));
1416 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_mac %02x:%02x:%02x:%02x:%02x:%02x\n", d_mac.u8[0],
1417 d_mac.u8[1], d_mac.u8[2], d_mac.u8[3], d_mac.u8[4], d_mac.u8[5]);
1418 BCMOLT_FIELD_SET(&c_val, classifier, dst_mac, d_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001419 }
1420
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001421 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001422 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001423 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001424 }
1425 */
1426
1427 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001428 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
1429 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001430 }
1431
1432 /*
1433 if (classifier.dst_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001434 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_ip, classifier.dst_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001435 }
1436
1437 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001438 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001439 }
1440 */
1441
1442 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001443 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
1444 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001445 }
1446
1447 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001448 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
1449 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001450 }
1451
1452 if (!classifier.pkt_tag_type().empty()) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001453 if (classifier.o_vid()) {
1454 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
1455 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
1456 }
1457
1458 if (classifier.i_vid()) {
1459 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
1460 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
1461 }
1462
1463 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
1464 if (classifier.pkt_tag_type().compare("untagged") == 0) {
1465 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
1466 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
1467 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
1468 single_tag = true;
1469
1470 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301471 // OpenOlt adapter will send 0xFF in case of no pbit classification
1472 // If it is any other value (0 to 7), it is for outer pbit classification.
1473 // OpenFlow protocol does not provide inner pbit classification (in case of double tagged packets),
1474 // and VOLTHA has not used any workaround to solve this problem (for ex: use metadata field).
1475 // Also there exists no use case for i-pbit classification, so we can safely ignore this for now.
1476 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001477 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301478 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001479 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
1480 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001481
Jason Huang09b73ea2020-01-08 17:52:05 +08001482 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301483 // Same comments as in case of "single_tag" packets.
1484 // 0xFF means no pbit classification, otherwise a valid PCP (0 to 7).
1485 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001486 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301487 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001488 }
1489 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001490 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001491 }
1492
Jason Huang09b73ea2020-01-08 17:52:05 +08001493 const ::openolt::ActionCmd& cmd = action.cmd();
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001494
Jason Huang09b73ea2020-01-08 17:52:05 +08001495 if (cmd.add_outer_tag()) {
1496 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
1497 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001498 }
1499
Jason Huang09b73ea2020-01-08 17:52:05 +08001500 if (cmd.remove_outer_tag()) {
1501 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
1502 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
1503 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301504
Jason Huang09b73ea2020-01-08 17:52:05 +08001505 if (action.o_vid()) {
1506 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
1507 o_vid = action.o_vid();
1508 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
1509 }
1510
1511 if (action.o_pbits()) {
1512 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
1513 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
1514 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301515
Jason Huang09b73ea2020-01-08 17:52:05 +08001516 if (action.i_vid()) {
1517 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
1518 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
1519 }
1520
1521 if (action.i_pbits()) {
1522 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
1523 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
1524 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301525
Jason Huang09b73ea2020-01-08 17:52:05 +08001526 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
1527
Shad Ansari39739bc2018-09-13 21:38:37 +00001528 if ((access_intf_id >= 0) && (onu_id >= 0)) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001529 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
1530 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
1531 tm_val.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, downstream);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001532
Jason Huang09b73ea2020-01-08 17:52:05 +08001533 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1534 // Queue 0 on DS subscriber scheduler
1535 tm_val.queue_id = 0;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001536
Jason Huang09b73ea2020-01-08 17:52:05 +08001537 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1538 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1539 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001540
Jason Huang09b73ea2020-01-08 17:52:05 +08001541 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1542 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1543 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001544
Jason Huang09b73ea2020-01-08 17:52:05 +08001545 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1546 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
1547 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001548
Jason Huang09b73ea2020-01-08 17:52:05 +08001549 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1550 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1551 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1552 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_q_set_id, tm_q_set_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001553
Jason Huang09b73ea2020-01-08 17:52:05 +08001554 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
1555 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1556 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1557 }
1558 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
1559 // NNI Scheduler ID
1560 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1561 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1562 // Queue 0 on NNI scheduler
1563 tm_val.queue_id = 0;
1564 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1565 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1566 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001567
Jason Huang09b73ea2020-01-08 17:52:05 +08001568 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001569 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1570 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1571
Jason Huang09b73ea2020-01-08 17:52:05 +08001572 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1573 /* Fetch TM QMP ID mapped to US NNI scheduler */
1574 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
1575 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1576 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1577 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1578 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_q_set_id, tm_q_set_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001579
Jason Huang09b73ea2020-01-08 17:52:05 +08001580 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001581 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1582 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001583 }
Shad Ansari39739bc2018-09-13 21:38:37 +00001584 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301585 } else {
1586 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1587 tm_val.queue_id = 0;
1588
1589 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
1590 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1591 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
1592
1593 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1594 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
1595 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00001596 }
1597
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001598 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001599
1600 // BAL 3.1 supports statistics only for unicast flows.
1601 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1602 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
1603 }
1604
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001605#ifdef FLOW_CHECKER
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001606 //Flow Checker, To avoid duplicate flow.
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001607 if (flow_id_counters != 0) {
1608 bool b_duplicate_flow = false;
Jason Huang09b73ea2020-01-08 17:52:05 +08001609 std::map<flow_pair, int>::iterator it;
1610
1611 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1612 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(it->first.first, it->first.second, ONU_ID)) && \
1613 (key.flow_type == it->first.second) && \
1614 (cfg.data.svc_port_id == get_flow_status(it->first.first, it->first.second, SVC_PORT_ID)) && \
1615 (cfg.data.priority == get_flow_status(it->first.first, it->first.second, PRIORITY)) && \
1616 (cfg.data.cookie == get_flow_status(it->first.first, it->first.second, COOKIE)) && \
1617 (cfg.data.ingress_intf.intf_type == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_TYPE)) && \
1618 (cfg.data.ingress_intf.intf_id == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_ID)) && \
1619 (cfg.data.egress_intf.intf_type == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_TYPE)) && \
1620 (cfg.data.egress_intf.intf_id == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_ID)) && \
1621 (c_val.o_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_VID)) && \
1622 (c_val.o_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_PBITS)) && \
1623 (c_val.i_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_VID)) && \
1624 (c_val.i_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_PBITS)) && \
1625 (c_val.ether_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_ETHER_TYPE)) && \
1626 (c_val.ip_proto == get_flow_status(it->first.first, it->first.second, CLASSIFIER_IP_PROTO)) && \
1627 (c_val.src_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_SRC_PORT)) && \
1628 (c_val.dst_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_DST_PORT)) && \
1629 (c_val.pkt_tag_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_PKT_TAG_TYPE)) && \
1630 (cfg.data.egress_qos.type == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TYPE)) && \
1631 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_QUEUE_ID)) && \
1632 (cfg.data.egress_qos.tm_sched.id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TM_SCHED_ID)) && \
1633 (a_val.cmds_bitmask == get_flow_status(it->first.first, it->first.second, ACTION_CMDS_BITMASK)) && \
1634 (a_val.o_vid == get_flow_status(it->first.first, it->first.second, ACTION_O_VID)) && \
1635 (a_val.i_vid == get_flow_status(it->first.first, it->first.second, ACTION_I_VID)) && \
1636 (a_val.o_pbits == get_flow_status(it->first.first, it->first.second, ACTION_O_PBITS)) && \
1637 (a_val.i_pbits == get_flow_status(it->first.first, it->first.second, ACTION_I_PBITS)) && \
1638 (cfg.data.state == get_flow_status(it->first.first, it->first.second, STATE)) && \
1639 (cfg.data.group_id == get_flow_status(it->first.first, it->first.second, GROUP_ID));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001640#ifdef SHOW_FLOW_PARAM
1641 // Flow Parameter
1642 FLOW_PARAM_LOG();
1643#endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001644 if (b_duplicate_flow) {
1645 FLOW_LOG(WARNING, "Flow duplicate", 0);
1646 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
1647 }
1648 }
1649 }
1650#endif
1651
1652 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
1653 if (err) {
1654 FLOW_LOG(ERROR, "Flow add failed", err);
1655 return bcm_to_grpc_err(err, "flow add failed");
1656 } else {
1657 FLOW_LOG(INFO, "Flow add ok", err);
1658 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08001659 flow_map[std::pair<int, int>(key.flow_id,key.flow_type)] = flow_map.size();
1660 flow_id_counters = flow_map.size();
1661 if (gemport_id > 0 && access_intf_id >= 0) {
1662 gem_id_intf_id gem_intf(gemport_id, access_intf_id);
1663 if (gem_ref_cnt.count(gem_intf) > 0) {
1664 // The gem port is already installed
1665 // Increment the ref counter indicating number of flows referencing this gem port
1666 gem_ref_cnt[gem_intf]++;
1667 OPENOLT_LOG(DEBUG, openolt_log_id, "incremented gem_ref_cnt, gem_ref_cnt=%d\n", gem_ref_cnt[gem_intf]);
1668 } else {
1669 // Initialize the refence count for the gemport.
1670 gem_ref_cnt[gem_intf] = 1;
1671 OPENOLT_LOG(DEBUG, openolt_log_id, "initialized gem_ref_cnt\n");
1672 }
1673 } else {
1674 OPENOLT_LOG(DEBUG, openolt_log_id, "not incrementing gem_ref_cnt flow_id=%d gemport_id=%d access_intf_id=%d\n", flow_id, gemport_id, access_intf_id);
1675 }
1676
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001677 bcmos_fastlock_unlock(&data_lock, 0);
1678 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04001679
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001680 return Status::OK;
1681}
1682
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001683Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
1684
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001685 bcmolt_flow_cfg cfg;
1686 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001687
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001688 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001689 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001690 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001691 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001692 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001693 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001694 } else if(flow_type.compare(multicast) == 0) {
1695 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001696 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001697 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001698 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
1699 }
1700
Jason Huang09b73ea2020-01-08 17:52:05 +08001701 OPENOLT_LOG(INFO, openolt_log_id, "flow remove received for flow_id=%u, flow_type=%s\n",
1702 flow_id, flow_type.c_str());
1703
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001704 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08001705 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
1706 int32_t gemport_id = -1;
1707 int32_t intf_id = -1;
1708 int16_t acl_id = -1;
1709 if (flow_to_acl_map.count(fl_id_fl_dir) > 0) {
1710 acl_id_gem_id_intf_id ac_id_gm_id_if_id = flow_to_acl_map[fl_id_fl_dir];
1711 acl_id = std::get<0>(ac_id_gm_id_if_id);
1712 gemport_id = std::get<1>(ac_id_gm_id_if_id);
1713 intf_id = std::get<2>(ac_id_gm_id_if_id);
1714 // cleanup acl only if it is a valid acl. If not valid acl, it may be datapath flow.
1715 if (acl_id >= 0) {
1716 Status resp = handle_acl_rule_cleanup(acl_id, gemport_id, intf_id, flow_type);
1717 bcmos_fastlock_unlock(&data_lock, 0);
1718 if (resp.ok()) {
1719 OPENOLT_LOG(INFO, openolt_log_id, "acl removed ok for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
1720 flow_to_acl_map.erase(fl_id_fl_dir);
1721 } else {
1722 OPENOLT_LOG(ERROR, openolt_log_id, "acl remove error for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
1723 }
1724 return resp;
1725 }
1726 }
1727
Craig Lutgen967a1d02018-11-27 10:41:51 -06001728 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001729 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06001730 flowid_to_gemport.erase(key.flow_id);
1731 port_to_flows[port_no].erase(key.flow_id);
1732 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
1733 }
1734 else
1735 {
1736 flowid_to_port.erase(key.flow_id);
1737 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001738 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001739
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001740 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001741
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001742 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001743 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001744 OPENOLT_LOG(ERROR, openolt_log_id, "Error while removing %s flow, flow_id=%d, err = %s\n", flow_type.c_str(), flow_id, bcmos_strerror(err));
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001745 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
1746 }
1747
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001748 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08001749 if (flow_id_counters != 0) {
1750 std::map<flow_pair, int>::iterator it;
1751 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1752 if (it->first.first == flow_id && it->first.second == key.flow_type) {
1753 flow_id_counters -= 1;
1754 flow_map.erase(it);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001755 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001756 }
1757 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001758 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
1759
1760 clear_gem_port(gemport_id, intf_id);
1761
1762 flow_to_acl_map.erase(fl_id_fl_dir);
1763
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001764 bcmos_fastlock_unlock(&data_lock, 0);
1765
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001766 return Status::OK;
1767}
1768
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001769bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
1770 bcmos_errno err;
1771 bcmolt_tm_sched_cfg tm_sched_cfg;
1772 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
1773 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
1774
Jason Huangbf45ffb2019-10-30 17:29:02 +08001775 //check TM scheduler has configured or not
1776 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
1777 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001778 #ifdef TEST_MODE
1779 // It is impossible to mock the setting of tm_sched_cfg.data.state because
1780 // the actual bcmolt_cfg_get passes the address of tm_sched_cfg.hdr and we cannot
1781 // set the tm_sched_cfg.data.state. So a new stub function is created and address
1782 // of tm_sched_cfg is passed. This is one-of case where we need to add test specific
1783 // code in production code.
1784 err = bcmolt_cfg_get__tm_sched_stub(dev_id, &tm_sched_cfg);
1785 #else
Jason Huangbf45ffb2019-10-30 17:29:02 +08001786 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001787 #endif
Jason Huangbf45ffb2019-10-30 17:29:02 +08001788 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001789 OPENOLT_LOG(ERROR, openolt_log_id, "cfg: Failed to query TM scheduler, err = %s\n",bcmos_strerror(err));
Jason Huangbf45ffb2019-10-30 17:29:02 +08001790 return err;
1791 }
1792 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
1793 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
1794 return BCM_ERR_OK;
1795 }
1796
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001797 // bcmbal_tm_sched_owner
1798 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
1799
1800 /**< The output of the tm_sched object instance */
1801 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
1802
1803 if (direction.compare(upstream) == 0) {
1804 // In upstream it is NNI scheduler
1805 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
1806 } else if (direction.compare(downstream) == 0) {
1807 // In downstream it is PON scheduler
1808 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
1809 }
1810
1811 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
1812
1813 // bcmbal_tm_sched_type
1814 // set the deafult policy to strict priority
1815 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
1816
1817 // num_priorities: Max number of strict priority scheduling elements
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001818 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, NUM_OF_PRIORITIES);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001819
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001820 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
1821 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001822 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
1823 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001824 return err;
1825 }
1826
1827 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
1828 direction.c_str(), tm_sched_key.id, intf_id);
1829 return BCM_ERR_OK;
1830}
1831
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001832bcmos_errno CreateSched(std::string direction, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t port_no,
1833 uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
1834 tech_profile::SchedulingPolicy sched_policy, tech_profile::TrafficShapingInfo tf_sh_info) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001835
1836 bcmos_errno err;
1837
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001838 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001839 bcmolt_tm_sched_cfg tm_sched_cfg;
1840 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
1841 tm_sched_key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001842
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001843 // bcmbal_tm_sched_owner
1844 // In downstream it is sub_term scheduler
1845 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001846
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001847 /**< The output of the tm_sched object instance */
1848 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001849
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001850 // bcmbal_tm_sched_parent
1851 // The parent for the sub_term scheduler is the PON scheduler in the downstream
1852 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
1853 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_param.u.priority.priority, priority);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001854 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001855 be achieved using the' virtual' type of attachment.
1856 tm_sched_owner.u.sub_term.intf_id = intf_id;
1857 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
1858 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001859
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001860 // bcmbal_tm_sched_type
1861 // set the deafult policy to strict priority
1862 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001863
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001864 // num_priorities: Max number of strict priority scheduling elements
1865 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001866
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001867 // bcmbal_tm_shaping
1868 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
1869 uint32_t cir = tf_sh_info.cir();
1870 uint32_t pir = tf_sh_info.pir();
1871 uint32_t burst = tf_sh_info.pbs();
1872 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
1873 cir, pir, burst);
1874 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
1875 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
1876 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
1877 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
1878 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
1879 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001880 }
1881
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001882 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001883 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001884 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001885intf_id %d, onu_id %d, uni_id %d, port_no %u, err = %s\n", tm_sched_key.id, intf_id, onu_id, uni_id, \
1886port_no, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001887 return err;
1888 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001889 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
1890uni_id %d, port_no %u\n", tm_sched_key.id, intf_id, onu_id, uni_id, port_no);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001891
1892 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001893 bcmolt_itupon_alloc_cfg cfg;
1894 bcmolt_itupon_alloc_key key = { };
1895 key.pon_ni = intf_id;
1896 key.alloc_id = alloc_id;
1897 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
Burak Gurdag03919c72020-02-04 22:46:57 +00001898 int pir_bw = tf_sh_info.pir()*125; // conversion from kbps to bytes/sec
1899 int cir_bw = tf_sh_info.cir()*125; // conversion from kbps to bytes/sec
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001900 //offset to match bandwidth granularity
1901 int offset_pir_bw = pir_bw%bw_granularity;
1902 int offset_cir_bw = cir_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001903
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001904 pir_bw = pir_bw - offset_pir_bw;
1905 cir_bw = cir_bw - offset_cir_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001906
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001907 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001908
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001909 switch (additional_bw) {
1910 case 2: //AdditionalBW_BestEffort
1911 if (pir_bw == 0) {
1912 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
1913%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001914 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001915 } else if (pir_bw < cir_bw) {
1916 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
1917bandwidth (%d)\n", pir_bw, cir_bw);
1918 return BCM_ERR_PARM;
1919 } else if (pir_bw == cir_bw) {
1920 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
1921bandwidth for additional bandwidth eligibility of type best_effort\n");
1922 return BCM_ERR_PARM;
1923 }
1924 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
1925 break;
1926 case 1: //AdditionalBW_NA
1927 if (pir_bw == 0) {
1928 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
1929%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
1930 return BCM_ERR_PARM;
1931 } else if (cir_bw == 0) {
1932 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
1933additional bandwidth eligibility of type Non-Assured (NA)\n");
1934 return BCM_ERR_PARM;
1935 } else if (pir_bw < cir_bw) {
1936 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
1937bandwidth (%d)\n", pir_bw, cir_bw);
1938 return BCM_ERR_PARM;
1939 } else if (pir_bw == cir_bw) {
1940 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
1941bandwidth for additional bandwidth eligibility of type non_assured\n");
1942 return BCM_ERR_PARM;
1943 }
1944 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
1945 break;
1946 case 0: //AdditionalBW_None
1947 if (pir_bw == 0) {
1948 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
194916000 bytes/sec\n");
1950 return BCM_ERR_PARM;
1951 } else if (cir_bw == 0) {
1952 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
1953for additional bandwidth eligibility of type None\n");
1954 return BCM_ERR_PARM;
1955 } else if (pir_bw > cir_bw) {
1956 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
1957for additional bandwidth eligibility of type None\n");
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001958 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001959bandwidth in None eligibility\n", pir_bw);
1960 cir_bw = pir_bw;
1961 } else if (pir_bw < cir_bw) {
1962 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
1963bandwidth (%d)\n", pir_bw, cir_bw);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001964 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001965bandwidth in None eligibility\n", pir_bw);
1966 cir_bw = pir_bw;
1967 }
1968 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
1969 break;
1970 default:
1971 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08001972 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001973 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
1974 in a fine granularity. */
1975 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
1976 /* Fixed Bandwidth with no critical requirement of shaping */
1977 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, 0);
1978 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
1979 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, cir_bw);
1980 /* Maximum allocated bandwidth allowed for this alloc ID */
1981 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
1982 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001983 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001984 for skipped allocations during quiet window */
1985 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
1986 /**< Allocation Profile index for CBR non-RT Bandwidth */
1987 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
1988 /**< Allocation Profile index for CBR RT Bandwidth */
1989 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
1990 /**< Alloc ID Weight used in case of Extended DBA mode */
1991 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
1992 /**< Alloc ID Priority used in case of Extended DBA mode */
1993 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
1994 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001995
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001996 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001997 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001998 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001999port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002000 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002001 }
Girish Gowdra96461052019-11-22 20:13:59 +05302002
2003 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
2004 if (err) {
2005 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2006port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
2007 return err;
2008 }
2009
2010 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
2011port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
2012
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002013 }
2014
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002015 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002016}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002017
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002018Status CreateTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2019 uint32_t intf_id = traffic_scheds->intf_id();
2020 uint32_t onu_id = traffic_scheds->onu_id();
2021 uint32_t uni_id = traffic_scheds->uni_id();
2022 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002023 std::string direction;
2024 unsigned int alloc_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002025 tech_profile::SchedulerConfig sched_config;
2026 tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002027 uint32_t priority;
2028 uint32_t weight;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002029 tech_profile::SchedulingPolicy sched_policy;
2030 tech_profile::TrafficShapingInfo traffic_shaping_info;
2031 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002032
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002033 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2034 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002035
2036 direction = GetDirection(traffic_sched.direction());
2037 if (direction.compare("direction-not-supported") == 0)
2038 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2039
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002040 alloc_id = traffic_sched.alloc_id();
2041 sched_config = traffic_sched.scheduler();
2042 additional_bw = sched_config.additional_bw();
2043 priority = sched_config.priority();
2044 weight = sched_config.weight();
2045 sched_policy = sched_config.sched_policy();
2046 traffic_shaping_info = traffic_sched.traffic_shaping_info();
2047 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
2048 sched_policy, traffic_shaping_info);
2049 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002050 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002051 return bcm_to_grpc_err(err, "Failed to create scheduler");
2052 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002053 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002054 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002055}
Jonathan Davis70c21812018-07-19 15:32:10 -04002056
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002057bcmos_errno RemoveSched(int intf_id, int onu_id, int uni_id, int alloc_id, std::string direction) {
Jonathan Davis70c21812018-07-19 15:32:10 -04002058
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002059 bcmos_errno err;
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302060 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302061 bcmolt_status los_status;
Girish Gowdra96461052019-11-22 20:13:59 +05302062 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002063
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002064 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002065 bcmolt_itupon_alloc_cfg cfg;
2066 bcmolt_itupon_alloc_key key = { };
2067 key.pon_ni = intf_id;
2068 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302069 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002070
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002071 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002072 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2073 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002074 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2075 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002076 return err;
2077 }
Girish Gowdra96461052019-11-22 20:13:59 +05302078
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302079 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302080 if (err == BCM_ERR_OK) {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302081 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_OFF) {
2082 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is enabled and LoS status is OFF, waiting for alloc cfg clear response\n",
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302083 intf_id);
2084 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2085 if (err) {
2086 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2087 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
2088 return err;
2089 }
2090 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302091 else if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_ON) {
2092 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is enabled but LoS status is ON, not waiting for alloc cfg clear response\n",
2093 intf_id);
2094 }
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302095 else if (state == BCMOLT_INTERFACE_STATE_INACTIVE) {
2096 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is disabled, not waiting for alloc cfg clear response\n",
2097 intf_id);
2098 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302099 } else {
2100 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch PON interface status, intf_id = %d, err = %s\n",
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302101 intf_id, bcmos_strerror(err));
Girish Gowdra96461052019-11-22 20:13:59 +05302102 return err;
2103 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002104 } else if (direction == downstream) {
2105 bcmolt_tm_sched_cfg cfg;
2106 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002107
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002108 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction)) {
2109 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
Girish Gowdra96461052019-11-22 20:13:59 +05302110 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002111 } else {
2112 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2113 return BCM_ERR_OK;
2114 }
Girish Gowdra96461052019-11-22 20:13:59 +05302115
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002116 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2117 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2118 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002119 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
2120intf_id %d, onu_id %d, err = %s\n", direction.c_str(), key.id, intf_id, onu_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002121 return err;
2122 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002123 }
2124
Girish Gowdra96461052019-11-22 20:13:59 +05302125 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d\n",
2126 direction.c_str(), sched_id, intf_id, onu_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002127 free_tm_sched_id(intf_id, onu_id, uni_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002128 return BCM_ERR_OK;
2129}
2130
2131Status RemoveTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2132 uint32_t intf_id = traffic_scheds->intf_id();
2133 uint32_t onu_id = traffic_scheds->onu_id();
2134 uint32_t uni_id = traffic_scheds->uni_id();
2135 std::string direction;
2136 bcmos_errno err;
2137
2138 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2139 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002140
2141 direction = GetDirection(traffic_sched.direction());
2142 if (direction.compare("direction-not-supported") == 0)
2143 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2144
2145 int alloc_id = traffic_sched.alloc_id();
2146 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002147 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002148 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002149 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2150 }
2151 }
2152 return Status::OK;
2153}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002154
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002155bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2156 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002157 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002158 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2159 bcmolt_tm_qmp_key tm_qmp_key;
2160 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002161
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002162 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2163 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002164 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed tm queue mapping profile count is 16.\n");
2165 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002166 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002167
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002168 tm_qmp_key.id = tm_qmp_id;
2169 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2170 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2171 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002172
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002173 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2174 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2175 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002176 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2177 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002178
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002179 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002180 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002181 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2182 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002183 return err;
2184 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002185
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002186 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2187 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002188 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002189}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002190
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002191bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2192 bcmos_errno err;
2193 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2194 bcmolt_tm_qmp_key tm_qmp_key;
2195 tm_qmp_key.id = tm_qmp_id;
2196
2197 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2198 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2199 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002200 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2201 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002202 return err;
2203 }
2204
2205 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2206 tm_qmp_key.id);
2207 return BCM_ERR_OK;
2208}
2209
2210bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2211 bcmos_errno err;
2212
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002213 /* Create default queues on the given PON/NNI scheduler */
2214 for (int queue_id = 0; queue_id < NUMBER_OF_DEFAULT_INTERFACE_QUEUES; queue_id++) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002215 bcmolt_tm_queue_cfg tm_queue_cfg;
2216 bcmolt_tm_queue_key tm_queue_key = {};
2217 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2218 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002219 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2220 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2221 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002222
2223 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2224 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2225 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2226
2227 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2228 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002229 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s tm queue, id %d, sched_id %d, tm_q_set_id %d, err = %s\n", \
2230 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002231 return err;
2232 }
2233
2234 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2235 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2236 }
2237 return BCM_ERR_OK;
2238}
2239
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002240bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
2241 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002242 bcmos_errno err;
2243 bcmolt_tm_queue_cfg cfg;
2244 bcmolt_tm_queue_key key = { };
2245 OPENOLT_LOG(INFO, openolt_log_id, "creating %s queue. access_intf_id = %d, onu_id = %d, uni_id = %d \
2246gemport_id = %d\n", direction.c_str(), access_intf_id, onu_id, uni_id, gemport_id);
2247
2248 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2249 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
2250
2251 if (priority > 7) {
2252 return BCM_ERR_RANGE;
2253 }
2254
2255 /* FIXME: The upstream queues have to be created once only.
2256 The upstream queues on the NNI scheduler are shared by all subscribers.
2257 When the first scheduler comes in, the queues get created, and are re-used by all others.
2258 Also, these queues should be present until the last subscriber exits the system.
2259 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2260
2261 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2262 for each GEM in TECH PROFILE */
2263 key.id = queue_id_list[priority];
2264
2265 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2266 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2267 key.id = 0;
2268 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2269 }
2270 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2271 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2272 }
2273 else {
2274 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2275 }
2276
2277 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2278
2279 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2280 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
2281
2282 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2283 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002284 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
2285sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n", \
2286 direction.c_str(), key.id, key.sched_id, key.tm_q_set_id, access_intf_id, onu_id, uni_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002287 return err;
2288 }
2289
2290 OPENOLT_LOG(INFO, openolt_log_id, "Created tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2291intf_id %d, onu_id %d, uni_id %d\n", direction.c_str(), key.id, key.sched_id, key.tm_q_set_id, access_intf_id, onu_id, uni_id);
2292 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002293}
2294
2295Status CreateTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2296 uint32_t intf_id = traffic_queues->intf_id();
2297 uint32_t onu_id = traffic_queues->onu_id();
2298 uint32_t uni_id = traffic_queues->uni_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002299 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002300 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002301 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002302 bcmolt_egress_qos_type qos_type = get_qos_type(intf_id, onu_id, uni_id, traffic_queues->traffic_queues_size());
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002303
2304 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2305 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2306 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2307 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2308 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
2309
2310 direction = GetDirection(traffic_queue.direction());
2311 if (direction.compare("direction-not-supported") == 0)
2312 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2313
2314 queues_priority_q[i] = traffic_queue.priority();
2315 queues_pbit_map[i] = traffic_queue.pbit_map();
2316 }
2317
2318 std::vector<uint32_t> tmq_map_profile(8, 0);
2319 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2320 queues_priority_q, COUNT_OF(queues_priority_q));
2321 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2322 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
2323
2324 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2325 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002326 err = CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2327 if (err != BCM_ERR_OK) {
2328 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2329 return bcm_to_grpc_err(err, "Failed to create tm queue mapping profile");
2330 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002331 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2332 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2333 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2334 }
2335 }
2336
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002337 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2338 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002339
2340 direction = GetDirection(traffic_queue.direction());
2341 if (direction.compare("direction-not-supported") == 0)
2342 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2343
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002344 err = CreateQueue(direction, intf_id, onu_id, uni_id, qos_type, traffic_queue.priority(), traffic_queue.gemport_id());
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002345
Girish Gowdruf26cf882019-05-01 23:47:58 -07002346 // If the queue exists already, lets not return failure and break the loop.
2347 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002348 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002349 return bcm_to_grpc_err(err, "Failed to create queue");
2350 }
2351 }
2352 return Status::OK;
2353}
2354
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002355bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
2356 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002357 bcmolt_tm_queue_cfg cfg;
2358 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002359 bcmos_errno err;
2360
2361 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002362 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction)) {
2363 key.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
2364 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002365 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002366 OPENOLT_LOG(INFO, openolt_log_id, "queue not present in DS. Not clearing, access_intf_id %d, onu_id %d, uni_id %d, gemport_id %d, direction %s\n", access_intf_id, onu_id, uni_id, gemport_id, direction.c_str());
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002367 return BCM_ERR_OK;
2368 }
2369 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002370 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2371 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002372 return BCM_ERR_OK;
2373 }
2374
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002375 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2376 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2377 // Reset the queue id to 0 when using fixed queue.
2378 key.id = 0;
2379 }
2380 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2381 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2382 }
2383 else {
2384 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2385 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002386
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002387 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2388 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002389 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002390 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, queue_id %d, sched_id %d, \
2391tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n",
2392 direction.c_str(), key.id, key.sched_id, key.tm_q_set_id, access_intf_id, onu_id, uni_id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002393 return err;
2394 }
2395
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002396 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2397intf_id %d, onu_id %d, uni_id %d\n", direction.c_str(), key.id, key.sched_id, key.tm_q_set_id, access_intf_id, onu_id, uni_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002398
2399 return BCM_ERR_OK;
2400}
2401
2402Status RemoveTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2403 uint32_t intf_id = traffic_queues->intf_id();
2404 uint32_t onu_id = traffic_queues->onu_id();
2405 uint32_t uni_id = traffic_queues->uni_id();
2406 uint32_t port_no = traffic_queues->port_no();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002407 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002408 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002409 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002410 bcmolt_egress_qos_type qos_type = get_qos_type(intf_id, onu_id, uni_id, traffic_queues->traffic_queues_size());
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002411
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002412 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2413 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002414
2415 direction = GetDirection(traffic_queue.direction());
2416 if (direction.compare("direction-not-supported") == 0)
2417 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2418
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002419 err = RemoveQueue(direction, intf_id, onu_id, uni_id, qos_type, traffic_queue.priority(), traffic_queue.gemport_id());
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002420 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002421 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002422 return bcm_to_grpc_err(err, "Failed to remove queue");
2423 }
Jonathan Davis70c21812018-07-19 15:32:10 -04002424 }
2425
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002426 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE && (direction.compare(upstream) == 0 || direction.compare(downstream) == 0 && is_tm_sched_id_present(intf_id, onu_id, uni_id, direction))) {
2427 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2428 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
2429
2430 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
2431 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002432 err = RemoveTrafficQueueMappingProfile(tm_qmp_id);
2433 if (err != BCM_ERR_OK) {
2434 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2435 return bcm_to_grpc_err(err, "Failed to remove tm queue mapping profile");
2436 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002437 }
2438 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002439 clear_qos_type(intf_id, onu_id, uni_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04002440 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04002441}
Jason Huangbf45ffb2019-10-30 17:29:02 +08002442
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002443Status PerformGroupOperation_(const openolt::Group *group_cfg) {
2444
2445 bcmos_errno err;
2446 bcmolt_group_key key = {};
2447 bcmolt_group_cfg grp_cfg_obj;
2448 bcmolt_group_members_update grp_mem_upd;
2449 bcmolt_members_update_command grp_mem_upd_cmd;
2450 bcmolt_group_member_info member_info = {};
2451 bcmolt_group_member_info_list_u8 members = {};
2452 bcmolt_intf_ref interface_ref = {};
2453 bcmolt_egress_qos egress_qos = {};
2454 bcmolt_tm_sched_ref tm_sched_ref = {};
2455 bcmolt_action a_val = {};
2456
2457 uint32_t group_id = group_cfg->group_id();
2458
2459 OPENOLT_LOG(INFO, openolt_log_id, "PerformGroupOperation request received for Group %d\n", group_id);
2460
2461 if (group_id >= 0) {
2462 key.id = group_id;
2463 }
2464 else {
2465 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
2466 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
2467 }
2468
2469 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2470 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
2471
2472 OPENOLT_LOG(INFO, openolt_log_id, "Checking if Group %d exists...\n",group_id);
2473
2474 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
2475 if (err != BCM_ERR_OK) {
2476 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
2477 return bcm_to_grpc_err(err, "Error in querying group");
2478 }
2479
2480 members.len = group_cfg->members_size();
2481
2482 // IMPORTANT: A member cannot be added to a group if the group type is not determined.
2483 // Group type is determined after a flow is assigned to it.
2484 // Therefore, a group must be created first, then a flow (with multicast type) must be assigned to it.
2485 // Only then we can add members to the group.
2486
2487 // if group does not exist, create it and return.
2488 if (grp_cfg_obj.data.state == BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
2489
2490 if (members.len != 0) {
2491 OPENOLT_LOG(ERROR, openolt_log_id, "Member list is not empty for non-existent Group %d. Members can be added only after a flow is assigned to this newly-created group.\n", group_id);
2492 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Non-empty member list given for non-existent group");
2493 } else {
2494
2495 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2496 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, cookie, key.id);
2497
2498 /* Setting group actions and action parameters, if any.
2499 Only remove_outer_tag and translate_inner_tag actions and i_vid action parameter
2500 are supported for multicast groups in BAL 3.1.
2501 */
2502 const ::openolt::Action& action = group_cfg->action();
2503 const ::openolt::ActionCmd &cmd = action.cmd();
2504
2505 bcmolt_action_cmd_id cmd_bmask = BCMOLT_ACTION_CMD_ID_NONE;
2506 if (cmd.remove_outer_tag()) {
2507 OPENOLT_LOG(INFO, openolt_log_id, "Action remove_outer_tag applied to Group %d.\n", group_id);
2508 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
2509 }
2510
2511 if (cmd.translate_inner_tag()) {
2512 OPENOLT_LOG(INFO, openolt_log_id, "Action translate_inner_tag applied to Group %d.\n", group_id);
2513 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG);
2514 }
2515
2516 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, cmd_bmask);
2517
2518 if (action.i_vid()) {
2519 OPENOLT_LOG(INFO, openolt_log_id, "Setting action parameter i_vid=%d for Group %d.\n", action.i_vid(), group_id);
2520 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
2521 }
2522
2523 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, action, a_val);
2524
2525 // Create group
2526 err = bcmolt_cfg_set(dev_id, &(grp_cfg_obj.hdr));
2527
2528 if (BCM_ERR_OK != err) {
2529 BCM_LOG(ERROR, openolt_log_id, "Failed to create Group %d, err = %s (%d)\n", key.id, bcmos_strerror(err), err);
2530 return bcm_to_grpc_err(err, "Error in creating group");
2531 }
2532
2533 BCM_LOG(INFO, openolt_log_id, "Group %d has been created and configured with empty member list.\n", key.id);
2534 return Status::OK;
2535 }
2536 }
2537
2538 // The group already exists. Continue configuring it according to the update member command.
2539
2540 OPENOLT_LOG(INFO, openolt_log_id, "Configuring existing Group %d.\n",group_id);
2541
2542 // MEMBER LIST CONSTRUCTION
2543 // Note that members.len can be 0 here. if the group already exists and the command is SET then sending
2544 // empty list to the group is a legit operation and this actually empties the member list.
2545 members.arr = (bcmolt_group_member_info*)bcmos_calloc((members.len)*sizeof(bcmolt_group_member_info));
2546
2547 if (!members.arr) {
2548 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to allocate memory for group member list.\n");
2549 return grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "Memory exhausted during member list creation");
2550 }
2551
2552 /* SET GROUP MEMBERS UPDATE COMMAND */
2553 openolt::Group::GroupMembersCommand command = group_cfg->command();
2554 switch(command) {
2555 case openolt::Group::SET_MEMBERS :
2556 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_SET;
2557 OPENOLT_LOG(INFO, openolt_log_id, "Setting %d members for Group %d.\n", members.len, group_id);
2558 break;
2559 case openolt::Group::ADD_MEMBERS :
2560 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_ADD;
2561 OPENOLT_LOG(INFO, openolt_log_id, "Adding %d members to Group %d.\n", members.len, group_id);
2562 break;
2563 case openolt::Group::REMOVE_MEMBERS :
2564 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_REMOVE;
2565 OPENOLT_LOG(INFO, openolt_log_id, "Removing %d members from Group %d.\n", members.len, group_id);
2566 break;
2567 default :
2568 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid value %d for group member command.\n", command);
2569 bcmos_free(members.arr);
2570 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group member command");
2571 }
2572
2573 // SET MEMBERS LIST
2574 for (int i = 0; i < members.len; i++) {
2575
2576 if (command == openolt::Group::REMOVE_MEMBERS) {
2577 OPENOLT_LOG(INFO, openolt_log_id, "Removing group member %d from group %d\n",i,key.id);
2578 } else {
2579 OPENOLT_LOG(INFO, openolt_log_id, "Adding group member %d to group %d\n",i,key.id);
2580 }
2581
2582 openolt::GroupMember *member = (openolt::GroupMember *) &group_cfg->members()[i];
2583
2584 // Set member interface type
2585 openolt::GroupMember::InterfaceType if_type = member->interface_type();
2586 switch(if_type){
2587 case openolt::GroupMember::PON :
2588 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_PON);
2589 OPENOLT_LOG(INFO, openolt_log_id, "Interface type PON is assigned to GroupMember %d\n",i);
2590 break;
2591 case openolt::GroupMember::EPON_1G_PATH :
2592 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_1_G);
2593 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_1G is assigned to GroupMember %d\n",i);
2594 break;
2595 case openolt::GroupMember::EPON_10G_PATH :
2596 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_10_G);
2597 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_10G is assigned to GroupMember %d\n",i);
2598 break;
2599 default :
2600 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid interface type value %d for GroupMember %d.\n",if_type,i);
2601 bcmos_free(members.arr);
2602 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface type for a group member");
2603 }
2604
2605 // Set member interface id
2606 if (member->interface_id() >= 0) {
2607 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_id, member->interface_id());
2608 OPENOLT_LOG(INFO, openolt_log_id, "Interface %d is assigned to GroupMember %d\n", member->interface_id(), i);
2609 } else {
2610 bcmos_free(members.arr);
2611 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface id for a group member");
2612 }
2613
2614 // Set member interface_ref
2615 BCMOLT_FIELD_SET(&member_info, group_member_info, intf, interface_ref);
2616
2617 // Set member gem_port_id. This must be a multicast gemport.
2618 if (member->gem_port_id() >= 0) {
2619 BCMOLT_FIELD_SET(&member_info, group_member_info, svc_port_id, member->gem_port_id());
2620 OPENOLT_LOG(INFO, openolt_log_id, "GEM Port %d is assigned to GroupMember %d\n", member->gem_port_id(), i);
2621 } else {
2622 bcmos_free(members.arr);
2623 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid gem port id for a group member");
2624 }
2625
2626 // Set member scheduler id and queue_id
2627 uint32_t tm_sched_id = get_default_tm_sched_id(member->interface_id(), downstream);
2628 OPENOLT_LOG(INFO, openolt_log_id, "Scheduler %d is assigned to GroupMember %d\n", tm_sched_id, i);
2629 BCMOLT_FIELD_SET(&tm_sched_ref, tm_sched_ref, id, tm_sched_id);
2630 BCMOLT_FIELD_SET(&egress_qos, egress_qos, tm_sched, tm_sched_ref);
2631
2632 // We assume that all multicast traffic destined to a PON port is using the same fixed queue.
2633 uint32_t tm_queue_id;
2634 if (member->priority() >= 0 && member->priority() < NUMBER_OF_DEFAULT_INTERFACE_QUEUES) {
2635 tm_queue_id = queue_id_list[member->priority()];
2636 OPENOLT_LOG(INFO, openolt_log_id, "Queue %d is assigned to GroupMember %d\n", tm_queue_id, i);
2637 BCMOLT_FIELD_SET(&egress_qos, egress_qos, type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2638 BCMOLT_FIELD_SET(&egress_qos.u.fixed_queue, egress_qos_fixed_queue, queue_id, tm_queue_id);
2639 } else {
2640 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid fixed queue priority/ID %d for GroupMember %d\n", member->priority(), i);
2641 bcmos_free(members.arr);
2642 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid queue priority for a group member");
2643 }
2644
2645 BCMOLT_FIELD_SET(&member_info, group_member_info, egress_qos, egress_qos);
2646 BCMOLT_ARRAY_ELEM_SET(&(members), i, member_info);
2647 }
2648
2649 BCMOLT_OPER_INIT(&grp_mem_upd, group, members_update, key);
2650 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.members, members);
2651 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.command, grp_mem_upd_cmd);
2652
2653 err = bcmolt_oper_submit(dev_id, &(grp_mem_upd.hdr));
2654 bcmos_free(members.arr);
2655
2656 if (BCM_ERR_OK != err) {
2657 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to submit members update operation for Group %d err = %s (%d)\n", key.id, bcmos_strerror(err), err);
2658 return bcm_to_grpc_err(err, "Failed to submit members update operation for the group");
2659 }
2660
2661 OPENOLT_LOG(INFO, openolt_log_id, "Successfully submitted members update operation for Group %d\n", key.id);
2662
2663 return Status::OK;
2664}