blob: c6ced4891a1ca84c2216e5c1634d478c590e2c92 [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);
Girish Gowdra1d018a52020-03-05 14:38:20 -0800156 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500157 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);
Girish Gowdra1d018a52020-03-05 14:38:20 -0800162 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500163 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);
Girish Gowdra1d018a52020-03-05 14:38:20 -0800183 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500184 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);
Girish Gowdra1d018a52020-03-05 14:38:20 -0800189 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500190 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,
Girish Gowdra24297032020-03-23 12:32:37 -0700773 BCMOLT_ONU_POST_DISCOVERY_MODE_NONE);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000774 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
Girish Gowdra24297032020-03-23 12:32:37 -0700984 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
985 bcmolt_onu_state onu_state;
986
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000987 onu_key.onu_id = onu_id;
988 onu_key.pon_ni = intf_id;
989 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
990 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Girish Gowdra24297032020-03-23 12:32:37 -0700991#ifdef TEST_MODE
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -0500992 // It is impossible to mock the setting of onu_cfg.data.onu_state because
993 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
994 // set the onu_cfg.data.onu_state. So a new stub function is created and address
995 // of onu_cfg is passed. This is one-of case where we need to add test specific
996 // code in production code.
997 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Girish Gowdra24297032020-03-23 12:32:37 -0700998#else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000999 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Girish Gowdra24297032020-03-23 12:32:37 -07001000#endif
1001 OPENOLT_LOG(INFO, openolt_log_id, "Activate ONU : old state = %d, current state = %d\n",
1002 onu_cfg.data.onu_old_state, onu_cfg.data.onu_state);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001003 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001004 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) {
1005 OPENOLT_LOG(INFO, openolt_log_id, "ONU is already in ACTIVE state, \
1006not processing this request for pon_intf=%d onu_id=%d\n", intf_id, onu_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001007 return Status::OK;
Girish Gowdra24297032020-03-23 12:32:37 -07001008 } else if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_NOT_CONFIGURED &&
1009 onu_cfg.data.onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1010 // We need the ONU to be in NOT_CONFIGURED or INACTIVE state to further process the request
1011 OPENOLT_LOG(ERROR, openolt_log_id, "ONU in an invalid state to process the request, \
1012state=%d pon_intf=%d onu_id=%d\n", onu_cfg.data.onu_state, intf_id, onu_id);
1013 return bcm_to_grpc_err(err, "Failed to activate ONU, invalid ONU state");
1014 }
1015 } else {
1016 // This should never happen. BAL GET should succeed for non-existant ONUs too. The state of such ONUs will be NOT_CONFIGURED
1017 OPENOLT_LOG(ERROR, openolt_log_id, "ONU state query failed pon_intf=%d onu_id=%d\n", intf_id, onu_id);
1018 return bcm_to_grpc_err(err, "onu get failed");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001019 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001020
Girish Gowdra24297032020-03-23 12:32:37 -07001021 // If the ONU is not configured at all we need to first configure it
1022 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_NOT_CONFIGURED) {
1023 OPENOLT_LOG(INFO, openolt_log_id, "Configuring ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001024vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Girish Gowdra24297032020-03-23 12:32:37 -07001025 vendor_specific_to_str(vendor_specific).c_str(), pir);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001026
Girish Gowdra24297032020-03-23 12:32:37 -07001027 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1028 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1029 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1030 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1031 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1032 /*set burst and data profiles to fec disabled*/
1033 if (board_technology == "XGS-PON") {
1034 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1035 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1036 } else if (board_technology == "GPON") {
1037 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1038 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1039 }
1040 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1041 if (err != BCM_ERR_OK) {
1042 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to configure ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
1043 return bcm_to_grpc_err(err, "Failed to configure ONU");
1044 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001045 }
Girish Gowdra24297032020-03-23 12:32:37 -07001046
1047 // Now that the ONU is configured, move the ONU to ACTIVE state
1048 memset(&onu_cfg, 0, sizeof(bcmolt_onu_cfg));
1049 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1050 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1051 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
1052 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
1053 onu_state, BCMOLT_ONU_OPERATION_ACTIVE);
1054 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001055 if (err != BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001056 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to activate ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001057 return bcm_to_grpc_err(err, "Failed to activate ONU");
1058 }
Girish Gowdra24297032020-03-23 12:32:37 -07001059 // ONU will eventually get activated after we have submitted the operation request. The adapter will receive an asynchronous
1060 // ONU_ACTIVATION_COMPLETED_INDICATION
1061
1062 OPENOLT_LOG(INFO, openolt_log_id, "Activated ONU, onu_id %d on PON %d\n", onu_id, intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001063
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001064 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001065}
1066
Jonathan Davis70c21812018-07-19 15:32:10 -04001067Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1068 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001069 bcmos_errno err = BCM_ERR_OK;
1070 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1071 bcmolt_onu_cfg onu_cfg;
1072 bcmolt_onu_key onu_key; /**< Object key. */
1073 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001074
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001075 onu_key.onu_id = onu_id;
1076 onu_key.pon_ni = intf_id;
1077 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1078 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001079 #ifdef TEST_MODE
1080 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1081 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1082 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1083 // of onu_cfg is passed. This is one-of case where we need to add test specific
1084 // code in production code.
1085 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001086 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001087 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001088 #endif
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301089 onu_state = onu_cfg.data.onu_state;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001090 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001091 switch (onu_state) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001092 case BCMOLT_ONU_STATE_ACTIVE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001093 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001094 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001095 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1096 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1097 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001098 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 +00001099 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1100 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301101 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 +00001102 break;
1103 }
Jonathan Davis70c21812018-07-19 15:32:10 -04001104 }
1105
1106 return Status::OK;
1107}
1108
1109Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001110 const char *vendor_id, const char *vendor_specific) {
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301111 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301112 bcmolt_onu_state onu_state;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001113
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001114 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 -05001115 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1116
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001117 // Need to deactivate before removing it (BAL rules)
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001118 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301119
1120 err = get_onu_status((bcmolt_interface)intf_id, onu_id, &onu_state);
1121 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001122 if (onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1123 OPENOLT_LOG(INFO, openolt_log_id, "waiting for onu deactivate complete response: intf_id=%d, onu_id=%d\n",
1124 intf_id, onu_id);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301125 err = wait_for_onu_deactivate_complete(intf_id, onu_id);
1126 if (err) {
1127 OPENOLT_LOG(ERROR, openolt_log_id, "failed to delete onu intf_id %d, onu_id %d\n",
1128 intf_id, onu_id);
1129 return bcm_to_grpc_err(err, "Failed to delete ONU");
1130 }
1131 }
Girish Gowdra24297032020-03-23 12:32:37 -07001132 else {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301133 OPENOLT_LOG(INFO, openolt_log_id, "Onu is Inactive, onu_id: %d, not waiting for onu deactivate complete response\n",
1134 intf_id);
1135 }
1136 }
1137 else {
1138 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch Onu status, onu_id = %d, intf_id = %d, err = %s\n",
1139 onu_id, intf_id, bcmos_strerror(err));
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301140 return bcm_to_grpc_err(err, "Failed to delete ONU");
1141 }
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001142
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001143 bcmolt_onu_cfg cfg_obj;
1144 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001145
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001146 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 -04001147 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001148
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001149 key.onu_id = onu_id;
1150 key.pon_ni = intf_id;
1151 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001152
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301153 err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001154 if (err != BCM_ERR_OK)
1155 {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001156 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 -04001157 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1158 }
1159
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301160 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 +00001161 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001162}
1163
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001164#define MAX_CHAR_LENGTH 20
1165#define MAX_OMCI_MSG_LENGTH 44
1166Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001167 bcmolt_bin_str buf = {};
1168 bcmolt_onu_cpu_packets omci_cpu_packets;
1169 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001170
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001171 key.pon_ni = intf_id;
1172 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001173
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001174 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1175 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1176 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001177
1178 // ???
1179 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1180 buf.len = MAX_OMCI_MSG_LENGTH;
1181 } else {
1182 buf.len = pkt.size()/2;
1183 }
1184
1185 /* Send the OMCI packet using the BAL remote proxy API */
1186 uint16_t idx1 = 0;
1187 uint16_t idx2 = 0;
1188 uint8_t arraySend[buf.len];
1189 char str1[MAX_CHAR_LENGTH];
1190 char str2[MAX_CHAR_LENGTH];
1191 memset(&arraySend, 0, buf.len);
1192
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001193 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1194 sprintf(str1,"%c", pkt[idx1]);
1195 sprintf(str2,"%c", pkt[++idx1]);
1196 strcat(str1,str2);
1197 arraySend[idx2] = strtol(str1, NULL, 16);
1198 }
1199
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001200 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1201 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001202
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001203 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1204 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1205 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001206
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001207 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001208 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001209 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 +00001210 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001211 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001212 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 -05001213 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001214 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001215 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001216
1217 return Status::OK;
1218}
1219
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001220Status 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 +00001221 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1222 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1223 bcmolt_bin_str buf = {};
1224 bcmolt_gem_port_id gem_port_id_array[1];
1225 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001226
Craig Lutgen967a1d02018-11-27 10:41:51 -06001227 if (port_no > 0) {
1228 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001229 if (gemport_id == 0) {
1230 bcmos_fastlock_lock(&data_lock);
1231 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1232 // Pick any flow that is mapped with the same port_no.
1233 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1234 if (it != port_to_flows.end() && !it->second.empty()) {
1235 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1236 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1237 if (fit != flowid_to_gemport.end()) {
1238 found = true;
1239 gemport_id = fit->second;
1240 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001241 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001242 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001243
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001244 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001245 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 -08001246 onu_id, port_no, intf_id);
1247 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1248 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001249 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 -08001250 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001251 }
1252
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001253 gem_port_id_array[0] = gemport_id;
1254 gem_port_list.len = 1;
1255 gem_port_list.arr = gem_port_id_array;
1256 buf.len = pkt.size();
1257 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1258 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1259
1260 /* init the API struct */
1261 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1262 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1263 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1264 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1265 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1266
1267 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1268 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1269
1270 /* call API */
1271 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001272 }
1273 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001274 //TODO: Port No is 0, it is coming sender requirement.
1275 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1276 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001277 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001278 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001279
1280 return Status::OK;
1281}
1282
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001283Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001284 bcmolt_flow_key key = {}; /* declare key */
1285 bcmolt_bin_str buffer = {};
1286 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001287
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001288 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
1289 bcmolt_flow_id flow_id = 0;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001290
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001291 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1292 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1293 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1294 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1295 key.flow_id = flow_id;
1296 else {
Jason Huang09b73ea2020-01-08 17:52:05 +08001297 if (flow_id_counters) {
1298 std::map<flow_pair, int>::iterator it;
1299 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1300 int flow_index = it->first.first;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001301 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1302 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1303 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1304 key.flow_id = flow_index;
1305 break;
1306 }
1307 }
1308 }
1309 else {
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001310 OPENOLT_LOG(ERROR, openolt_log_id, "no flow id found for uplink packetout\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001311 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1312 }
1313 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001314
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001315 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001316
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001317 /* Initialize the API struct. */
1318 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001319
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001320 buffer.len = pkt.size();
1321 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1322 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1323 if (buffer.arr == NULL) {
1324 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1325 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1326 }
1327 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1328
1329 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1330 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001331 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 -05001332 return bcm_to_grpc_err(BCM_ERR_SYSCALL_ERR, "Error sending packets via nni port");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001333 } else {
1334 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1335 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001336
1337 return Status::OK;
1338}
Craig Lutgen967a1d02018-11-27 10:41:51 -06001339Status 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 +00001340 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001341 int32_t alloc_id, int32_t network_intf_id,
1342 int32_t gemport_id, const ::openolt::Classifier& classifier,
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001343 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie,
1344 int32_t group_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001345 bcmolt_flow_cfg cfg;
1346 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001347 int32_t o_vid = -1;
1348 bool single_tag = false;
1349 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001350 bcmolt_classifier c_val = { };
1351 bcmolt_action a_val = { };
1352 bcmolt_tm_queue_ref tm_val = { };
1353 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05001354 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001355
Jason Huang09b73ea2020-01-08 17:52:05 +08001356 OPENOLT_LOG(INFO, openolt_log_id, "flow add received for flow_id=%u, flow_type=%s\n", flow_id, flow_type.c_str());
1357
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001358 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001359 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001360 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001361 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001362 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001363 } else if (flow_type.compare(multicast) == 0) {
1364 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001365 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001366 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001367 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001368 }
1369
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001370 BCMOLT_CFG_INIT(&cfg, flow, key);
1371 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001372
Jason Huang09b73ea2020-01-08 17:52:05 +08001373 if (action.cmd().trap_to_host()) {
1374 Status resp = handle_acl_rule_install(onu_id, flow_id, flow_type, access_intf_id,
1375 network_intf_id, gemport_id, classifier);
1376 return resp;
1377 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001378
1379 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1380
1381 if (access_intf_id >= 0 && network_intf_id >= 0) {
1382 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1383 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1384 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08001385 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1386 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001387 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1388 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1389 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1390 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1391 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001392 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001393 } else {
1394 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
1395 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001396 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001397
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001398 if (onu_id >= 0) {
1399 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
1400 }
1401 if (gemport_id >= 0) {
1402 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
1403 }
1404 if (gemport_id >= 0 && port_no != 0) {
1405 bcmos_fastlock_lock(&data_lock);
1406 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
1407 port_to_flows[port_no].insert(key.flow_id);
1408 flowid_to_gemport[key.flow_id] = gemport_id;
1409 }
1410 else
1411 {
1412 flowid_to_port[key.flow_id] = port_no;
1413 }
1414 bcmos_fastlock_unlock(&data_lock, 0);
1415 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001416 if (gemport_id >= 0 && access_intf_id >= 0) {
1417 // Update the flow_to_acl_map. Note that since this is a datapath flow, acl_id is -1
1418 // This info is needed during flow remove where we need to retrieve the gemport_id
1419 // and access_intf id for the given flow id and flow direction.
1420 // After retrieving the ACL ID and GEM PORT ID, we decrement the corresponding
1421 // reference counters for those ACL ID and GEMPORT ID.
1422 acl_id_gem_id_intf_id ac_id_gm_id_if_id(-1, gemport_id, access_intf_id);
1423 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
1424 bcmos_fastlock_lock(&data_lock);
1425 flow_to_acl_map[fl_id_fl_dir] = ac_id_gm_id_if_id;
1426 bcmos_fastlock_unlock(&data_lock, 0);
1427 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001428 if (priority_value >= 0) {
1429 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
1430 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301431
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001432 } else { // MULTICAST FLOW
1433 if (group_id >= 0) {
1434 BCMOLT_MSG_FIELD_SET(&cfg, group_id, group_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001435 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001436 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1437 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001438 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001439
1440 {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001441 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001442 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001443 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
1444 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001445 }
1446
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001447 if (classifier.dst_mac().size() > 0) {
1448 bcmos_mac_address d_mac = {};
1449 bcmos_mac_address_init(&d_mac);
1450 memcpy(d_mac.u8, classifier.dst_mac().data(), sizeof(d_mac.u8));
1451 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_mac %02x:%02x:%02x:%02x:%02x:%02x\n", d_mac.u8[0],
1452 d_mac.u8[1], d_mac.u8[2], d_mac.u8[3], d_mac.u8[4], d_mac.u8[5]);
1453 BCMOLT_FIELD_SET(&c_val, classifier, dst_mac, d_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001454 }
1455
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001456 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001457 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001458 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001459 }
1460 */
1461
1462 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001463 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
1464 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001465 }
1466
1467 /*
1468 if (classifier.dst_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001469 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_ip, classifier.dst_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001470 }
1471
1472 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001473 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001474 }
1475 */
1476
1477 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001478 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
1479 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001480 }
1481
1482 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001483 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
1484 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001485 }
1486
1487 if (!classifier.pkt_tag_type().empty()) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001488 if (classifier.o_vid()) {
1489 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
1490 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
1491 }
1492
1493 if (classifier.i_vid()) {
1494 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
1495 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
1496 }
1497
1498 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
1499 if (classifier.pkt_tag_type().compare("untagged") == 0) {
1500 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
1501 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
1502 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
1503 single_tag = true;
1504
1505 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301506 // OpenOlt adapter will send 0xFF in case of no pbit classification
1507 // If it is any other value (0 to 7), it is for outer pbit classification.
1508 // OpenFlow protocol does not provide inner pbit classification (in case of double tagged packets),
1509 // and VOLTHA has not used any workaround to solve this problem (for ex: use metadata field).
1510 // Also there exists no use case for i-pbit classification, so we can safely ignore this for now.
1511 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001512 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301513 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001514 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
1515 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001516
Jason Huang09b73ea2020-01-08 17:52:05 +08001517 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301518 // Same comments as in case of "single_tag" packets.
1519 // 0xFF means no pbit classification, otherwise a valid PCP (0 to 7).
1520 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001521 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301522 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001523 }
1524 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001525 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001526 }
1527
Jason Huang09b73ea2020-01-08 17:52:05 +08001528 const ::openolt::ActionCmd& cmd = action.cmd();
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001529
Jason Huang09b73ea2020-01-08 17:52:05 +08001530 if (cmd.add_outer_tag()) {
1531 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
1532 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001533 }
1534
Jason Huang09b73ea2020-01-08 17:52:05 +08001535 if (cmd.remove_outer_tag()) {
1536 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
1537 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
1538 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301539
Jason Huang09b73ea2020-01-08 17:52:05 +08001540 if (action.o_vid()) {
1541 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
1542 o_vid = action.o_vid();
1543 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
1544 }
1545
1546 if (action.o_pbits()) {
1547 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
1548 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
1549 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301550
Jason Huang09b73ea2020-01-08 17:52:05 +08001551 if (action.i_vid()) {
1552 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
1553 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
1554 }
1555
1556 if (action.i_pbits()) {
1557 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
1558 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
1559 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301560
Jason Huang09b73ea2020-01-08 17:52:05 +08001561 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
1562
Shad Ansari39739bc2018-09-13 21:38:37 +00001563 if ((access_intf_id >= 0) && (onu_id >= 0)) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001564 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
1565 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
1566 tm_val.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, downstream);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001567
Jason Huang09b73ea2020-01-08 17:52:05 +08001568 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1569 // Queue 0 on DS subscriber scheduler
1570 tm_val.queue_id = 0;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001571
Jason Huang09b73ea2020-01-08 17:52:05 +08001572 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1573 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1574 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001575
Jason Huang09b73ea2020-01-08 17:52:05 +08001576 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1577 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1578 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001579
Jason Huang09b73ea2020-01-08 17:52:05 +08001580 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1581 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
1582 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 +00001583
Jason Huang09b73ea2020-01-08 17:52:05 +08001584 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1585 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1586 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1587 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 +00001588
Jason Huang09b73ea2020-01-08 17:52:05 +08001589 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
1590 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1591 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1592 }
1593 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
1594 // NNI Scheduler ID
1595 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1596 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1597 // Queue 0 on NNI scheduler
1598 tm_val.queue_id = 0;
1599 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1600 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1601 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001602
Jason Huang09b73ea2020-01-08 17:52:05 +08001603 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 +00001604 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1605 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1606
Jason Huang09b73ea2020-01-08 17:52:05 +08001607 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1608 /* Fetch TM QMP ID mapped to US NNI scheduler */
1609 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
1610 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1611 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1612 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1613 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 +00001614
Jason Huang09b73ea2020-01-08 17:52:05 +08001615 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 +00001616 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1617 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001618 }
Shad Ansari39739bc2018-09-13 21:38:37 +00001619 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301620 } else {
1621 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1622 tm_val.queue_id = 0;
1623
1624 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
1625 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1626 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
1627
1628 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1629 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
1630 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00001631 }
1632
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001633 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001634
1635 // BAL 3.1 supports statistics only for unicast flows.
1636 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1637 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
1638 }
1639
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001640#ifdef FLOW_CHECKER
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001641 //Flow Checker, To avoid duplicate flow.
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001642 if (flow_id_counters != 0) {
1643 bool b_duplicate_flow = false;
Jason Huang09b73ea2020-01-08 17:52:05 +08001644 std::map<flow_pair, int>::iterator it;
1645
1646 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1647 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(it->first.first, it->first.second, ONU_ID)) && \
1648 (key.flow_type == it->first.second) && \
1649 (cfg.data.svc_port_id == get_flow_status(it->first.first, it->first.second, SVC_PORT_ID)) && \
1650 (cfg.data.priority == get_flow_status(it->first.first, it->first.second, PRIORITY)) && \
1651 (cfg.data.cookie == get_flow_status(it->first.first, it->first.second, COOKIE)) && \
1652 (cfg.data.ingress_intf.intf_type == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_TYPE)) && \
1653 (cfg.data.ingress_intf.intf_id == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_ID)) && \
1654 (cfg.data.egress_intf.intf_type == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_TYPE)) && \
1655 (cfg.data.egress_intf.intf_id == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_ID)) && \
1656 (c_val.o_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_VID)) && \
1657 (c_val.o_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_PBITS)) && \
1658 (c_val.i_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_VID)) && \
1659 (c_val.i_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_PBITS)) && \
1660 (c_val.ether_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_ETHER_TYPE)) && \
1661 (c_val.ip_proto == get_flow_status(it->first.first, it->first.second, CLASSIFIER_IP_PROTO)) && \
1662 (c_val.src_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_SRC_PORT)) && \
1663 (c_val.dst_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_DST_PORT)) && \
1664 (c_val.pkt_tag_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_PKT_TAG_TYPE)) && \
1665 (cfg.data.egress_qos.type == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TYPE)) && \
1666 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_QUEUE_ID)) && \
1667 (cfg.data.egress_qos.tm_sched.id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TM_SCHED_ID)) && \
1668 (a_val.cmds_bitmask == get_flow_status(it->first.first, it->first.second, ACTION_CMDS_BITMASK)) && \
1669 (a_val.o_vid == get_flow_status(it->first.first, it->first.second, ACTION_O_VID)) && \
1670 (a_val.i_vid == get_flow_status(it->first.first, it->first.second, ACTION_I_VID)) && \
1671 (a_val.o_pbits == get_flow_status(it->first.first, it->first.second, ACTION_O_PBITS)) && \
1672 (a_val.i_pbits == get_flow_status(it->first.first, it->first.second, ACTION_I_PBITS)) && \
1673 (cfg.data.state == get_flow_status(it->first.first, it->first.second, STATE)) && \
1674 (cfg.data.group_id == get_flow_status(it->first.first, it->first.second, GROUP_ID));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001675#ifdef SHOW_FLOW_PARAM
1676 // Flow Parameter
1677 FLOW_PARAM_LOG();
1678#endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001679 if (b_duplicate_flow) {
1680 FLOW_LOG(WARNING, "Flow duplicate", 0);
1681 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
1682 }
1683 }
1684 }
1685#endif
1686
1687 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
1688 if (err) {
1689 FLOW_LOG(ERROR, "Flow add failed", err);
1690 return bcm_to_grpc_err(err, "flow add failed");
1691 } else {
1692 FLOW_LOG(INFO, "Flow add ok", err);
1693 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08001694 flow_map[std::pair<int, int>(key.flow_id,key.flow_type)] = flow_map.size();
1695 flow_id_counters = flow_map.size();
1696 if (gemport_id > 0 && access_intf_id >= 0) {
1697 gem_id_intf_id gem_intf(gemport_id, access_intf_id);
1698 if (gem_ref_cnt.count(gem_intf) > 0) {
1699 // The gem port is already installed
1700 // Increment the ref counter indicating number of flows referencing this gem port
1701 gem_ref_cnt[gem_intf]++;
1702 OPENOLT_LOG(DEBUG, openolt_log_id, "incremented gem_ref_cnt, gem_ref_cnt=%d\n", gem_ref_cnt[gem_intf]);
1703 } else {
1704 // Initialize the refence count for the gemport.
1705 gem_ref_cnt[gem_intf] = 1;
1706 OPENOLT_LOG(DEBUG, openolt_log_id, "initialized gem_ref_cnt\n");
1707 }
1708 } else {
1709 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);
1710 }
1711
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001712 bcmos_fastlock_unlock(&data_lock, 0);
1713 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04001714
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001715 return Status::OK;
1716}
1717
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001718Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
1719
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001720 bcmolt_flow_cfg cfg;
1721 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001722
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001723 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001724 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001725 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001726 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001727 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001728 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001729 } else if(flow_type.compare(multicast) == 0) {
1730 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001731 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001732 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001733 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
1734 }
1735
Jason Huang09b73ea2020-01-08 17:52:05 +08001736 OPENOLT_LOG(INFO, openolt_log_id, "flow remove received for flow_id=%u, flow_type=%s\n",
1737 flow_id, flow_type.c_str());
1738
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001739 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08001740 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
1741 int32_t gemport_id = -1;
1742 int32_t intf_id = -1;
1743 int16_t acl_id = -1;
1744 if (flow_to_acl_map.count(fl_id_fl_dir) > 0) {
1745 acl_id_gem_id_intf_id ac_id_gm_id_if_id = flow_to_acl_map[fl_id_fl_dir];
1746 acl_id = std::get<0>(ac_id_gm_id_if_id);
1747 gemport_id = std::get<1>(ac_id_gm_id_if_id);
1748 intf_id = std::get<2>(ac_id_gm_id_if_id);
1749 // cleanup acl only if it is a valid acl. If not valid acl, it may be datapath flow.
1750 if (acl_id >= 0) {
1751 Status resp = handle_acl_rule_cleanup(acl_id, gemport_id, intf_id, flow_type);
1752 bcmos_fastlock_unlock(&data_lock, 0);
1753 if (resp.ok()) {
1754 OPENOLT_LOG(INFO, openolt_log_id, "acl removed ok for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
1755 flow_to_acl_map.erase(fl_id_fl_dir);
1756 } else {
1757 OPENOLT_LOG(ERROR, openolt_log_id, "acl remove error for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
1758 }
1759 return resp;
1760 }
1761 }
1762
Craig Lutgen967a1d02018-11-27 10:41:51 -06001763 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001764 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06001765 flowid_to_gemport.erase(key.flow_id);
1766 port_to_flows[port_no].erase(key.flow_id);
1767 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
1768 }
1769 else
1770 {
1771 flowid_to_port.erase(key.flow_id);
1772 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001773 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001774
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001775 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001776
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001777 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001778 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001779 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 -04001780 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
1781 }
1782
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001783 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08001784 if (flow_id_counters != 0) {
1785 std::map<flow_pair, int>::iterator it;
1786 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1787 if (it->first.first == flow_id && it->first.second == key.flow_type) {
1788 flow_id_counters -= 1;
1789 flow_map.erase(it);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001790 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001791 }
1792 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001793 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
1794
1795 clear_gem_port(gemport_id, intf_id);
1796
1797 flow_to_acl_map.erase(fl_id_fl_dir);
1798
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001799 bcmos_fastlock_unlock(&data_lock, 0);
1800
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001801 return Status::OK;
1802}
1803
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001804bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
1805 bcmos_errno err;
1806 bcmolt_tm_sched_cfg tm_sched_cfg;
1807 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
1808 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
1809
Jason Huangbf45ffb2019-10-30 17:29:02 +08001810 //check TM scheduler has configured or not
1811 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
1812 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001813 #ifdef TEST_MODE
1814 // It is impossible to mock the setting of tm_sched_cfg.data.state because
1815 // the actual bcmolt_cfg_get passes the address of tm_sched_cfg.hdr and we cannot
1816 // set the tm_sched_cfg.data.state. So a new stub function is created and address
1817 // of tm_sched_cfg is passed. This is one-of case where we need to add test specific
1818 // code in production code.
1819 err = bcmolt_cfg_get__tm_sched_stub(dev_id, &tm_sched_cfg);
1820 #else
Jason Huangbf45ffb2019-10-30 17:29:02 +08001821 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001822 #endif
Jason Huangbf45ffb2019-10-30 17:29:02 +08001823 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001824 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 +08001825 return err;
1826 }
1827 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
1828 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
1829 return BCM_ERR_OK;
1830 }
1831
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001832 // bcmbal_tm_sched_owner
1833 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
1834
1835 /**< The output of the tm_sched object instance */
1836 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
1837
1838 if (direction.compare(upstream) == 0) {
1839 // In upstream it is NNI scheduler
1840 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
1841 } else if (direction.compare(downstream) == 0) {
1842 // In downstream it is PON scheduler
1843 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
1844 }
1845
1846 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
1847
1848 // bcmbal_tm_sched_type
1849 // set the deafult policy to strict priority
1850 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
1851
1852 // num_priorities: Max number of strict priority scheduling elements
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001853 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, NUM_OF_PRIORITIES);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001854
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001855 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
1856 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001857 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
1858 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001859 return err;
1860 }
1861
1862 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
1863 direction.c_str(), tm_sched_key.id, intf_id);
1864 return BCM_ERR_OK;
1865}
1866
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001867bcmos_errno CreateSched(std::string direction, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t port_no,
1868 uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
1869 tech_profile::SchedulingPolicy sched_policy, tech_profile::TrafficShapingInfo tf_sh_info) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001870
1871 bcmos_errno err;
1872
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001873 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001874 bcmolt_tm_sched_cfg tm_sched_cfg;
1875 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
1876 tm_sched_key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001877
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001878 // bcmbal_tm_sched_owner
1879 // In downstream it is sub_term scheduler
1880 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001881
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001882 /**< The output of the tm_sched object instance */
1883 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001884
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001885 // bcmbal_tm_sched_parent
1886 // The parent for the sub_term scheduler is the PON scheduler in the downstream
1887 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
1888 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 +00001889 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001890 be achieved using the' virtual' type of attachment.
1891 tm_sched_owner.u.sub_term.intf_id = intf_id;
1892 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
1893 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001894
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001895 // bcmbal_tm_sched_type
1896 // set the deafult policy to strict priority
1897 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001898
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001899 // num_priorities: Max number of strict priority scheduling elements
1900 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001901
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001902 // bcmbal_tm_shaping
1903 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
1904 uint32_t cir = tf_sh_info.cir();
1905 uint32_t pir = tf_sh_info.pir();
1906 uint32_t burst = tf_sh_info.pbs();
1907 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
1908 cir, pir, burst);
1909 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
1910 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
1911 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
1912 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
1913 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
1914 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001915 }
1916
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001917 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001918 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001919 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001920intf_id %d, onu_id %d, uni_id %d, port_no %u, err = %s\n", tm_sched_key.id, intf_id, onu_id, uni_id, \
1921port_no, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001922 return err;
1923 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001924 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
1925uni_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 -08001926
1927 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001928 bcmolt_itupon_alloc_cfg cfg;
1929 bcmolt_itupon_alloc_key key = { };
1930 key.pon_ni = intf_id;
1931 key.alloc_id = alloc_id;
1932 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
Burak Gurdag03919c72020-02-04 22:46:57 +00001933 int pir_bw = tf_sh_info.pir()*125; // conversion from kbps to bytes/sec
1934 int cir_bw = tf_sh_info.cir()*125; // conversion from kbps to bytes/sec
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001935 //offset to match bandwidth granularity
1936 int offset_pir_bw = pir_bw%bw_granularity;
1937 int offset_cir_bw = cir_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001938
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001939 pir_bw = pir_bw - offset_pir_bw;
1940 cir_bw = cir_bw - offset_cir_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001941
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001942 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001943
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001944 switch (additional_bw) {
1945 case 2: //AdditionalBW_BestEffort
1946 if (pir_bw == 0) {
1947 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
1948%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001949 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001950 } else if (pir_bw < cir_bw) {
1951 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
1952bandwidth (%d)\n", pir_bw, cir_bw);
1953 return BCM_ERR_PARM;
1954 } else if (pir_bw == cir_bw) {
1955 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
1956bandwidth for additional bandwidth eligibility of type best_effort\n");
1957 return BCM_ERR_PARM;
1958 }
1959 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
1960 break;
1961 case 1: //AdditionalBW_NA
1962 if (pir_bw == 0) {
1963 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
1964%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
1965 return BCM_ERR_PARM;
1966 } else if (cir_bw == 0) {
1967 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
1968additional bandwidth eligibility of type Non-Assured (NA)\n");
1969 return BCM_ERR_PARM;
1970 } else if (pir_bw < cir_bw) {
1971 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
1972bandwidth (%d)\n", pir_bw, cir_bw);
1973 return BCM_ERR_PARM;
1974 } else if (pir_bw == cir_bw) {
1975 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
1976bandwidth for additional bandwidth eligibility of type non_assured\n");
1977 return BCM_ERR_PARM;
1978 }
1979 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
1980 break;
1981 case 0: //AdditionalBW_None
1982 if (pir_bw == 0) {
1983 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
198416000 bytes/sec\n");
1985 return BCM_ERR_PARM;
1986 } else if (cir_bw == 0) {
1987 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
1988for additional bandwidth eligibility of type None\n");
1989 return BCM_ERR_PARM;
1990 } else if (pir_bw > cir_bw) {
1991 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
1992for additional bandwidth eligibility of type None\n");
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001993 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001994bandwidth in None eligibility\n", pir_bw);
1995 cir_bw = pir_bw;
1996 } else if (pir_bw < cir_bw) {
1997 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
1998bandwidth (%d)\n", pir_bw, cir_bw);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001999 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002000bandwidth in None eligibility\n", pir_bw);
2001 cir_bw = pir_bw;
2002 }
2003 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2004 break;
2005 default:
2006 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002007 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002008 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2009 in a fine granularity. */
2010 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
2011 /* Fixed Bandwidth with no critical requirement of shaping */
2012 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, 0);
2013 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
2014 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, cir_bw);
2015 /* Maximum allocated bandwidth allowed for this alloc ID */
2016 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
2017 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002018 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002019 for skipped allocations during quiet window */
2020 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2021 /**< Allocation Profile index for CBR non-RT Bandwidth */
2022 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2023 /**< Allocation Profile index for CBR RT Bandwidth */
2024 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2025 /**< Alloc ID Weight used in case of Extended DBA mode */
2026 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2027 /**< Alloc ID Priority used in case of Extended DBA mode */
2028 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2029 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002030
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002031 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002032 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002033 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 -05002034port_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 -08002035 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002036 }
Girish Gowdra96461052019-11-22 20:13:59 +05302037
2038 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
2039 if (err) {
2040 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2041port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
2042 return err;
2043 }
2044
2045 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
2046port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
2047
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002048 }
2049
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002050 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002051}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002052
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002053Status CreateTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2054 uint32_t intf_id = traffic_scheds->intf_id();
2055 uint32_t onu_id = traffic_scheds->onu_id();
2056 uint32_t uni_id = traffic_scheds->uni_id();
2057 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002058 std::string direction;
2059 unsigned int alloc_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002060 tech_profile::SchedulerConfig sched_config;
2061 tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002062 uint32_t priority;
2063 uint32_t weight;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002064 tech_profile::SchedulingPolicy sched_policy;
2065 tech_profile::TrafficShapingInfo traffic_shaping_info;
2066 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002067
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002068 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2069 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002070
2071 direction = GetDirection(traffic_sched.direction());
2072 if (direction.compare("direction-not-supported") == 0)
2073 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2074
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002075 alloc_id = traffic_sched.alloc_id();
2076 sched_config = traffic_sched.scheduler();
2077 additional_bw = sched_config.additional_bw();
2078 priority = sched_config.priority();
2079 weight = sched_config.weight();
2080 sched_policy = sched_config.sched_policy();
2081 traffic_shaping_info = traffic_sched.traffic_shaping_info();
2082 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
2083 sched_policy, traffic_shaping_info);
2084 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002085 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002086 return bcm_to_grpc_err(err, "Failed to create scheduler");
2087 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002088 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002089 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002090}
Jonathan Davis70c21812018-07-19 15:32:10 -04002091
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002092bcmos_errno RemoveSched(int intf_id, int onu_id, int uni_id, int alloc_id, std::string direction) {
Jonathan Davis70c21812018-07-19 15:32:10 -04002093
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002094 bcmos_errno err;
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302095 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302096 bcmolt_status los_status;
Girish Gowdra96461052019-11-22 20:13:59 +05302097 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002098
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002099 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002100 bcmolt_itupon_alloc_cfg cfg;
2101 bcmolt_itupon_alloc_key key = { };
2102 key.pon_ni = intf_id;
2103 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302104 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002105
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002106 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002107 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2108 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002109 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2110 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002111 return err;
2112 }
Girish Gowdra96461052019-11-22 20:13:59 +05302113
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302114 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302115 if (err == BCM_ERR_OK) {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302116 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_OFF) {
2117 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 +05302118 intf_id);
2119 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2120 if (err) {
2121 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2122 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
2123 return err;
2124 }
2125 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302126 else if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_ON) {
2127 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is enabled but LoS status is ON, not waiting for alloc cfg clear response\n",
2128 intf_id);
2129 }
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302130 else if (state == BCMOLT_INTERFACE_STATE_INACTIVE) {
2131 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is disabled, not waiting for alloc cfg clear response\n",
2132 intf_id);
2133 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302134 } else {
2135 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 +05302136 intf_id, bcmos_strerror(err));
Girish Gowdra96461052019-11-22 20:13:59 +05302137 return err;
2138 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002139 } else if (direction == downstream) {
2140 bcmolt_tm_sched_cfg cfg;
2141 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002142
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002143 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction)) {
2144 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
Girish Gowdra96461052019-11-22 20:13:59 +05302145 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002146 } else {
2147 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2148 return BCM_ERR_OK;
2149 }
Girish Gowdra96461052019-11-22 20:13:59 +05302150
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002151 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2152 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2153 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002154 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
2155intf_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 +00002156 return err;
2157 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002158 }
2159
Girish Gowdra96461052019-11-22 20:13:59 +05302160 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d\n",
2161 direction.c_str(), sched_id, intf_id, onu_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002162 free_tm_sched_id(intf_id, onu_id, uni_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002163 return BCM_ERR_OK;
2164}
2165
2166Status RemoveTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2167 uint32_t intf_id = traffic_scheds->intf_id();
2168 uint32_t onu_id = traffic_scheds->onu_id();
2169 uint32_t uni_id = traffic_scheds->uni_id();
2170 std::string direction;
2171 bcmos_errno err;
2172
2173 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2174 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002175
2176 direction = GetDirection(traffic_sched.direction());
2177 if (direction.compare("direction-not-supported") == 0)
2178 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2179
2180 int alloc_id = traffic_sched.alloc_id();
2181 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002182 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002183 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002184 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2185 }
2186 }
2187 return Status::OK;
2188}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002189
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002190bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2191 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002192 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002193 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2194 bcmolt_tm_qmp_key tm_qmp_key;
2195 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002196
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002197 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2198 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002199 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed tm queue mapping profile count is 16.\n");
2200 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002201 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002202
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002203 tm_qmp_key.id = tm_qmp_id;
2204 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2205 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2206 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002207
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002208 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2209 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2210 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002211 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2212 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002213
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002214 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002215 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002216 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2217 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002218 return err;
2219 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002220
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002221 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2222 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002223 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002224}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002225
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002226bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2227 bcmos_errno err;
2228 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2229 bcmolt_tm_qmp_key tm_qmp_key;
2230 tm_qmp_key.id = tm_qmp_id;
2231
2232 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2233 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2234 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002235 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2236 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002237 return err;
2238 }
2239
2240 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2241 tm_qmp_key.id);
2242 return BCM_ERR_OK;
2243}
2244
2245bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2246 bcmos_errno err;
2247
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002248 /* Create default queues on the given PON/NNI scheduler */
2249 for (int queue_id = 0; queue_id < NUMBER_OF_DEFAULT_INTERFACE_QUEUES; queue_id++) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002250 bcmolt_tm_queue_cfg tm_queue_cfg;
2251 bcmolt_tm_queue_key tm_queue_key = {};
2252 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2253 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002254 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2255 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2256 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002257
2258 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2259 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2260 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2261
2262 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2263 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002264 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", \
2265 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 +00002266 return err;
2267 }
2268
2269 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2270 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2271 }
2272 return BCM_ERR_OK;
2273}
2274
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002275bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
2276 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002277 bcmos_errno err;
2278 bcmolt_tm_queue_cfg cfg;
2279 bcmolt_tm_queue_key key = { };
2280 OPENOLT_LOG(INFO, openolt_log_id, "creating %s queue. access_intf_id = %d, onu_id = %d, uni_id = %d \
2281gemport_id = %d\n", direction.c_str(), access_intf_id, onu_id, uni_id, gemport_id);
2282
2283 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2284 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
2285
2286 if (priority > 7) {
2287 return BCM_ERR_RANGE;
2288 }
2289
2290 /* FIXME: The upstream queues have to be created once only.
2291 The upstream queues on the NNI scheduler are shared by all subscribers.
2292 When the first scheduler comes in, the queues get created, and are re-used by all others.
2293 Also, these queues should be present until the last subscriber exits the system.
2294 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2295
2296 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2297 for each GEM in TECH PROFILE */
2298 key.id = queue_id_list[priority];
2299
2300 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2301 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2302 key.id = 0;
2303 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2304 }
2305 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2306 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2307 }
2308 else {
2309 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2310 }
2311
2312 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2313
2314 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2315 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
2316
2317 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2318 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002319 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
2320sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n", \
2321 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 +00002322 return err;
2323 }
2324
2325 OPENOLT_LOG(INFO, openolt_log_id, "Created tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2326intf_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);
2327 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002328}
2329
2330Status CreateTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2331 uint32_t intf_id = traffic_queues->intf_id();
2332 uint32_t onu_id = traffic_queues->onu_id();
2333 uint32_t uni_id = traffic_queues->uni_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002334 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002335 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002336 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002337 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 +00002338
2339 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2340 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2341 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2342 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2343 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
2344
2345 direction = GetDirection(traffic_queue.direction());
2346 if (direction.compare("direction-not-supported") == 0)
2347 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2348
2349 queues_priority_q[i] = traffic_queue.priority();
2350 queues_pbit_map[i] = traffic_queue.pbit_map();
2351 }
2352
2353 std::vector<uint32_t> tmq_map_profile(8, 0);
2354 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2355 queues_priority_q, COUNT_OF(queues_priority_q));
2356 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2357 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
2358
2359 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2360 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002361 err = CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2362 if (err != BCM_ERR_OK) {
2363 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2364 return bcm_to_grpc_err(err, "Failed to create tm queue mapping profile");
2365 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002366 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2367 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2368 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2369 }
2370 }
2371
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002372 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2373 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002374
2375 direction = GetDirection(traffic_queue.direction());
2376 if (direction.compare("direction-not-supported") == 0)
2377 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2378
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002379 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 +00002380
Girish Gowdruf26cf882019-05-01 23:47:58 -07002381 // If the queue exists already, lets not return failure and break the loop.
2382 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002383 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002384 return bcm_to_grpc_err(err, "Failed to create queue");
2385 }
2386 }
2387 return Status::OK;
2388}
2389
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002390bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
2391 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002392 bcmolt_tm_queue_cfg cfg;
2393 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002394 bcmos_errno err;
2395
2396 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002397 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction)) {
2398 key.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
2399 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002400 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002401 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 -08002402 return BCM_ERR_OK;
2403 }
2404 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002405 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2406 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002407 return BCM_ERR_OK;
2408 }
2409
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002410 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2411 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2412 // Reset the queue id to 0 when using fixed queue.
2413 key.id = 0;
2414 }
2415 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2416 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2417 }
2418 else {
2419 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2420 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002421
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002422 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2423 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002424 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002425 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, queue_id %d, sched_id %d, \
2426tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n",
2427 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 -08002428 return err;
2429 }
2430
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002431 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2432intf_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 -08002433
2434 return BCM_ERR_OK;
2435}
2436
2437Status RemoveTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2438 uint32_t intf_id = traffic_queues->intf_id();
2439 uint32_t onu_id = traffic_queues->onu_id();
2440 uint32_t uni_id = traffic_queues->uni_id();
2441 uint32_t port_no = traffic_queues->port_no();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002442 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002443 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002444 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002445 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 +00002446
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002447 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2448 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002449
2450 direction = GetDirection(traffic_queue.direction());
2451 if (direction.compare("direction-not-supported") == 0)
2452 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2453
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002454 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 -08002455 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002456 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002457 return bcm_to_grpc_err(err, "Failed to remove queue");
2458 }
Jonathan Davis70c21812018-07-19 15:32:10 -04002459 }
2460
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002461 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))) {
2462 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2463 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
2464
2465 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
2466 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002467 err = RemoveTrafficQueueMappingProfile(tm_qmp_id);
2468 if (err != BCM_ERR_OK) {
2469 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2470 return bcm_to_grpc_err(err, "Failed to remove tm queue mapping profile");
2471 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002472 }
2473 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002474 clear_qos_type(intf_id, onu_id, uni_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04002475 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04002476}
Jason Huangbf45ffb2019-10-30 17:29:02 +08002477
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002478Status PerformGroupOperation_(const openolt::Group *group_cfg) {
2479
2480 bcmos_errno err;
2481 bcmolt_group_key key = {};
2482 bcmolt_group_cfg grp_cfg_obj;
2483 bcmolt_group_members_update grp_mem_upd;
2484 bcmolt_members_update_command grp_mem_upd_cmd;
2485 bcmolt_group_member_info member_info = {};
2486 bcmolt_group_member_info_list_u8 members = {};
2487 bcmolt_intf_ref interface_ref = {};
2488 bcmolt_egress_qos egress_qos = {};
2489 bcmolt_tm_sched_ref tm_sched_ref = {};
2490 bcmolt_action a_val = {};
2491
2492 uint32_t group_id = group_cfg->group_id();
2493
2494 OPENOLT_LOG(INFO, openolt_log_id, "PerformGroupOperation request received for Group %d\n", group_id);
2495
2496 if (group_id >= 0) {
2497 key.id = group_id;
2498 }
2499 else {
2500 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
2501 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
2502 }
2503
2504 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2505 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
2506
2507 OPENOLT_LOG(INFO, openolt_log_id, "Checking if Group %d exists...\n",group_id);
2508
2509 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
2510 if (err != BCM_ERR_OK) {
2511 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
2512 return bcm_to_grpc_err(err, "Error in querying group");
2513 }
2514
2515 members.len = group_cfg->members_size();
2516
2517 // IMPORTANT: A member cannot be added to a group if the group type is not determined.
2518 // Group type is determined after a flow is assigned to it.
2519 // Therefore, a group must be created first, then a flow (with multicast type) must be assigned to it.
2520 // Only then we can add members to the group.
2521
2522 // if group does not exist, create it and return.
2523 if (grp_cfg_obj.data.state == BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
2524
2525 if (members.len != 0) {
2526 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);
2527 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Non-empty member list given for non-existent group");
2528 } else {
2529
2530 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2531 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, cookie, key.id);
2532
2533 /* Setting group actions and action parameters, if any.
2534 Only remove_outer_tag and translate_inner_tag actions and i_vid action parameter
2535 are supported for multicast groups in BAL 3.1.
2536 */
2537 const ::openolt::Action& action = group_cfg->action();
2538 const ::openolt::ActionCmd &cmd = action.cmd();
2539
2540 bcmolt_action_cmd_id cmd_bmask = BCMOLT_ACTION_CMD_ID_NONE;
2541 if (cmd.remove_outer_tag()) {
2542 OPENOLT_LOG(INFO, openolt_log_id, "Action remove_outer_tag applied to Group %d.\n", group_id);
2543 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
2544 }
2545
2546 if (cmd.translate_inner_tag()) {
2547 OPENOLT_LOG(INFO, openolt_log_id, "Action translate_inner_tag applied to Group %d.\n", group_id);
2548 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG);
2549 }
2550
2551 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, cmd_bmask);
2552
2553 if (action.i_vid()) {
2554 OPENOLT_LOG(INFO, openolt_log_id, "Setting action parameter i_vid=%d for Group %d.\n", action.i_vid(), group_id);
2555 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
2556 }
2557
2558 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, action, a_val);
2559
2560 // Create group
2561 err = bcmolt_cfg_set(dev_id, &(grp_cfg_obj.hdr));
2562
2563 if (BCM_ERR_OK != err) {
2564 BCM_LOG(ERROR, openolt_log_id, "Failed to create Group %d, err = %s (%d)\n", key.id, bcmos_strerror(err), err);
2565 return bcm_to_grpc_err(err, "Error in creating group");
2566 }
2567
2568 BCM_LOG(INFO, openolt_log_id, "Group %d has been created and configured with empty member list.\n", key.id);
2569 return Status::OK;
2570 }
2571 }
2572
2573 // The group already exists. Continue configuring it according to the update member command.
2574
2575 OPENOLT_LOG(INFO, openolt_log_id, "Configuring existing Group %d.\n",group_id);
2576
2577 // MEMBER LIST CONSTRUCTION
2578 // Note that members.len can be 0 here. if the group already exists and the command is SET then sending
2579 // empty list to the group is a legit operation and this actually empties the member list.
2580 members.arr = (bcmolt_group_member_info*)bcmos_calloc((members.len)*sizeof(bcmolt_group_member_info));
2581
2582 if (!members.arr) {
2583 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to allocate memory for group member list.\n");
2584 return grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "Memory exhausted during member list creation");
2585 }
2586
2587 /* SET GROUP MEMBERS UPDATE COMMAND */
2588 openolt::Group::GroupMembersCommand command = group_cfg->command();
2589 switch(command) {
2590 case openolt::Group::SET_MEMBERS :
2591 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_SET;
2592 OPENOLT_LOG(INFO, openolt_log_id, "Setting %d members for Group %d.\n", members.len, group_id);
2593 break;
2594 case openolt::Group::ADD_MEMBERS :
2595 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_ADD;
2596 OPENOLT_LOG(INFO, openolt_log_id, "Adding %d members to Group %d.\n", members.len, group_id);
2597 break;
2598 case openolt::Group::REMOVE_MEMBERS :
2599 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_REMOVE;
2600 OPENOLT_LOG(INFO, openolt_log_id, "Removing %d members from Group %d.\n", members.len, group_id);
2601 break;
2602 default :
2603 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid value %d for group member command.\n", command);
2604 bcmos_free(members.arr);
2605 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group member command");
2606 }
2607
2608 // SET MEMBERS LIST
2609 for (int i = 0; i < members.len; i++) {
2610
2611 if (command == openolt::Group::REMOVE_MEMBERS) {
2612 OPENOLT_LOG(INFO, openolt_log_id, "Removing group member %d from group %d\n",i,key.id);
2613 } else {
2614 OPENOLT_LOG(INFO, openolt_log_id, "Adding group member %d to group %d\n",i,key.id);
2615 }
2616
2617 openolt::GroupMember *member = (openolt::GroupMember *) &group_cfg->members()[i];
2618
2619 // Set member interface type
2620 openolt::GroupMember::InterfaceType if_type = member->interface_type();
2621 switch(if_type){
2622 case openolt::GroupMember::PON :
2623 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_PON);
2624 OPENOLT_LOG(INFO, openolt_log_id, "Interface type PON is assigned to GroupMember %d\n",i);
2625 break;
2626 case openolt::GroupMember::EPON_1G_PATH :
2627 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_1_G);
2628 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_1G is assigned to GroupMember %d\n",i);
2629 break;
2630 case openolt::GroupMember::EPON_10G_PATH :
2631 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_10_G);
2632 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_10G is assigned to GroupMember %d\n",i);
2633 break;
2634 default :
2635 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid interface type value %d for GroupMember %d.\n",if_type,i);
2636 bcmos_free(members.arr);
2637 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface type for a group member");
2638 }
2639
2640 // Set member interface id
2641 if (member->interface_id() >= 0) {
2642 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_id, member->interface_id());
2643 OPENOLT_LOG(INFO, openolt_log_id, "Interface %d is assigned to GroupMember %d\n", member->interface_id(), i);
2644 } else {
2645 bcmos_free(members.arr);
2646 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface id for a group member");
2647 }
2648
2649 // Set member interface_ref
2650 BCMOLT_FIELD_SET(&member_info, group_member_info, intf, interface_ref);
2651
2652 // Set member gem_port_id. This must be a multicast gemport.
2653 if (member->gem_port_id() >= 0) {
2654 BCMOLT_FIELD_SET(&member_info, group_member_info, svc_port_id, member->gem_port_id());
2655 OPENOLT_LOG(INFO, openolt_log_id, "GEM Port %d is assigned to GroupMember %d\n", member->gem_port_id(), i);
2656 } else {
2657 bcmos_free(members.arr);
2658 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid gem port id for a group member");
2659 }
2660
2661 // Set member scheduler id and queue_id
2662 uint32_t tm_sched_id = get_default_tm_sched_id(member->interface_id(), downstream);
2663 OPENOLT_LOG(INFO, openolt_log_id, "Scheduler %d is assigned to GroupMember %d\n", tm_sched_id, i);
2664 BCMOLT_FIELD_SET(&tm_sched_ref, tm_sched_ref, id, tm_sched_id);
2665 BCMOLT_FIELD_SET(&egress_qos, egress_qos, tm_sched, tm_sched_ref);
2666
2667 // We assume that all multicast traffic destined to a PON port is using the same fixed queue.
2668 uint32_t tm_queue_id;
2669 if (member->priority() >= 0 && member->priority() < NUMBER_OF_DEFAULT_INTERFACE_QUEUES) {
2670 tm_queue_id = queue_id_list[member->priority()];
2671 OPENOLT_LOG(INFO, openolt_log_id, "Queue %d is assigned to GroupMember %d\n", tm_queue_id, i);
2672 BCMOLT_FIELD_SET(&egress_qos, egress_qos, type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2673 BCMOLT_FIELD_SET(&egress_qos.u.fixed_queue, egress_qos_fixed_queue, queue_id, tm_queue_id);
2674 } else {
2675 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid fixed queue priority/ID %d for GroupMember %d\n", member->priority(), i);
2676 bcmos_free(members.arr);
2677 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid queue priority for a group member");
2678 }
2679
2680 BCMOLT_FIELD_SET(&member_info, group_member_info, egress_qos, egress_qos);
2681 BCMOLT_ARRAY_ELEM_SET(&(members), i, member_info);
2682 }
2683
2684 BCMOLT_OPER_INIT(&grp_mem_upd, group, members_update, key);
2685 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.members, members);
2686 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.command, grp_mem_upd_cmd);
2687
2688 err = bcmolt_oper_submit(dev_id, &(grp_mem_upd.hdr));
2689 bcmos_free(members.arr);
2690
2691 if (BCM_ERR_OK != err) {
2692 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);
2693 return bcm_to_grpc_err(err, "Failed to submit members update operation for the group");
2694 }
2695
2696 OPENOLT_LOG(INFO, openolt_log_id, "Successfully submitted members update operation for Group %d\n", key.id);
2697
2698 return Status::OK;
2699}