blob: 147582cc836085eeb569d584a76a10eee6faf71e [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,
Burak Gurdag2f2618c2020-04-23 13:20:30 +000070 tech_profile::TrafficShapingInfo traffic_shaping_info, uint32_t tech_profile_id);
71static bcmos_errno RemoveSched(int intf_id, int onu_id, int uni_id, int alloc_id, std::string direction, int tech_profile_id);
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, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +000073 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id, uint32_t tech_profile_id);
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -050074static bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +000075 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id, uint32_t tech_profile_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
Jason Huang5d9ab1a2020-04-15 16:53:49 +080093bcmolt_stat_alarm_config set_stat_alarm_config(const openolt::OnuItuPonAlarm* request) {
94 bcmolt_stat_alarm_config alarm_cfg = {};
95 bcmolt_stat_alarm_trigger_config trigger_obj = {};
96 bcmolt_stat_alarm_soak_config soak_obj = {};
97
98 switch (request->alarm_reporting_condition()) {
99 case openolt::OnuItuPonAlarm::RATE_THRESHOLD:
100 trigger_obj.type = BCMOLT_STAT_CONDITION_TYPE_RATE_THRESHOLD;
101 BCMOLT_FIELD_SET(&trigger_obj.u.rate_threshold, stat_alarm_trigger_config_rate_threshold,
102 rising, request->rate_threshold_config().rate_threshold_rising());
103 BCMOLT_FIELD_SET(&trigger_obj.u.rate_threshold, stat_alarm_trigger_config_rate_threshold,
104 falling, request->rate_threshold_config().rate_threshold_falling());
105 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, active_soak_time,
106 request->rate_threshold_config().soak_time().active_soak_time());
107 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, clear_soak_time,
108 request->rate_threshold_config().soak_time().clear_soak_time());
109 break;
110 case openolt::OnuItuPonAlarm::RATE_RANGE:
111 trigger_obj.type = BCMOLT_STAT_CONDITION_TYPE_RATE_RANGE;
112 BCMOLT_FIELD_SET(&trigger_obj.u.rate_range, stat_alarm_trigger_config_rate_range, upper,
113 request->rate_range_config().rate_range_upper());
114 BCMOLT_FIELD_SET(&trigger_obj.u.rate_range, stat_alarm_trigger_config_rate_range, lower,
115 request->rate_range_config().rate_range_lower());
116 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, active_soak_time,
117 request->rate_range_config().soak_time().active_soak_time());
118 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, clear_soak_time,
119 request->rate_range_config().soak_time().clear_soak_time());
120 break;
121 case openolt::OnuItuPonAlarm::VALUE_THRESHOLD:
122 trigger_obj.type = BCMOLT_STAT_CONDITION_TYPE_VALUE_THRESHOLD;
123 BCMOLT_FIELD_SET(&trigger_obj.u.value_threshold, stat_alarm_trigger_config_value_threshold,
124 limit, request->value_threshold_config().threshold_limit());
125 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, active_soak_time,
126 request->value_threshold_config().soak_time().active_soak_time());
127 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, clear_soak_time,
128 request->value_threshold_config().soak_time().clear_soak_time());
129 break;
130 default:
131 OPENOLT_LOG(ERROR, openolt_log_id, "unsupported alarm reporting condition = %u\n", request->alarm_reporting_condition());
132 // For now just log the error and not return error. We can handle this scenario in the future.
133 break;
134 }
135
136 BCMOLT_FIELD_SET(&alarm_cfg, stat_alarm_config, trigger, trigger_obj);
137 BCMOLT_FIELD_SET(&alarm_cfg, stat_alarm_config, soak, soak_obj);
138
139 return alarm_cfg;
140}
141
142Status OnuItuPonAlarmSet_(const openolt::OnuItuPonAlarm* request) {
143 bcmos_errno err;
144 bcmolt_onu_itu_pon_stats_cfg stat_cfg; /* declare main API struct */
145 bcmolt_onu_key key = {}; /* declare key */
146 bcmolt_stat_alarm_config errors_cfg = {};
147
148 key.pon_ni = request->pon_ni();
149 key.onu_id = request->onu_id();
150
151 /* Initialize the API struct. */
152 BCMOLT_STAT_CFG_INIT(&stat_cfg, onu, itu_pon_stats, key);
153
154 /*
155 1. BCMOLT_STAT_CONDITION_TYPE_NONE = 0, The alarm is disabled.
156 2. BCMOLT_STAT_CONDITION_TYPE_RATE_THRESHOLD = 1, The alarm is triggered if the stats delta value between samples
157 crosses the configured threshold boundary.
158 rising: The alarm is raised if the stats delta value per second becomes greater than this threshold level.
159 falling: The alarm is cleared if the stats delta value per second becomes less than this threshold level.
160 3. BCMOLT_STAT_CONDITION_TYPE_RATE_RANGE = 2, The alarm is triggered if the stats delta value between samples
161 deviates from the configured range.
162 upper: The alarm is raised if the stats delta value per second becomes greater than this upper level.
163 lower: The alarm is raised if the stats delta value per second becomes less than this lower level.
164 4. BCMOLT_STAT_CONDITION_TYPE_VALUE_THRESHOLD = 3, The alarm is raised if the stats sample value becomes greater
165 than this level. The alarm is cleared when the host read the stats.
166 limit: The alarm is raised if the stats sample value becomes greater than this level.
167 The alarm is cleared when the host clears the stats.
168
169 active_soak_time: If the alarm condition is raised and stays in the raised state for at least this amount
170 of time (unit=seconds), the alarm indication is sent to the host.
171 The OLT delays the alarm indication no less than this delay period.
172 It can be delayed more than this period because of the statistics sampling interval.
173 clear_soak_time: After the alarm is raised, if it is cleared and stays in the cleared state for at least
174 this amount of time (unit=seconds), the alarm indication is sent to the host.
175 The OLT delays the alarm indication no less than this delay period. It can be delayed more
176 than this period because of the statistics sampling interval.
177 */
178
179 errors_cfg = set_stat_alarm_config(request);
180
181 switch (request->alarm_id()) {
182 case openolt::OnuItuPonAlarm_AlarmID::OnuItuPonAlarm_AlarmID_RDI_ERRORS:
183 //set the rdi_errors alarm
184 BCMOLT_FIELD_SET(&stat_cfg.data, onu_itu_pon_stats_cfg_data, rdi_errors, errors_cfg);
185 break;
186 default:
187 OPENOLT_LOG(ERROR, openolt_log_id, "could not find the alarm id %d\n", request->alarm_id());
188 return bcm_to_grpc_err(BCM_ERR_PARM, "the alarm id is wrong");
189 }
190
191 err = bcmolt_stat_cfg_set(dev_id, &stat_cfg.hdr);
192 if (err != BCM_ERR_OK) {
193 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to set onu itu pon stats, alarm id %d, pon_ni %d, onu_id %d, err = %s\n",
194 request->alarm_id(), key.pon_ni, key.onu_id, bcmos_strerror(err));
195 return bcm_to_grpc_err(err, "set Onu ITU PON stats alarm faild");
196 } else {
197 OPENOLT_LOG(INFO, openolt_log_id, "set onu itu pon stats alarm %d successfully, pon_ni %d, onu_id %d\n",
198 request->alarm_id(), key.pon_ni, key.onu_id);
199 }
200
201 return Status::OK;
202}
203
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400204Status GetDeviceInfo_(openolt::DeviceInfo* device_info) {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500205 device_info->set_vendor(VENDOR_ID);
206 device_info->set_model(MODEL_ID);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400207 device_info->set_hardware_version("");
208 device_info->set_firmware_version(firmware_version);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500209 device_info->set_technology(board_technology);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500210 device_info->set_pon_ports(num_of_pon_ports);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500211
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800212 char serial_number[OPENOLT_FIELD_LEN];
213 memset(serial_number, '\0', OPENOLT_FIELD_LEN);
214 openolt_read_sysinfo("Serial Number", serial_number);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000215 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device serial number %s\n", serial_number);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800216 device_info->set_device_serial_number(serial_number);
217
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700218 char device_id[OPENOLT_FIELD_LEN];
219 memset(device_id, '\0', OPENOLT_FIELD_LEN);
Humera Kouser6143c9e2020-06-17 22:37:31 +0530220
221 if (grpc_server_interface_name != NULL) {
222 if (get_intf_mac(grpc_server_interface_name, device_id, sizeof(device_id)) != NULL)
223 {
224 OPENOLT_LOG(INFO, openolt_log_id, "Fetched mac address %s of an interface %s\n", device_id, grpc_server_interface_name);
225 }
226 else
227 {
228 OPENOLT_LOG(ERROR, openolt_log_id, "Mac address of an interface %s is NULL\n", grpc_server_interface_name);
229 }
230 }
231 else
232 {
233 openolt_read_sysinfo("MAC", device_id);
234 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device mac address %s\n", device_id);
235 }
236
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700237 device_info->set_device_id(device_id);
238
Craig Lutgenb2601f02018-10-23 13:04:31 -0500239 // Legacy, device-wide ranges. To be deprecated when adapter
240 // is upgraded to support per-interface ranges
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000241 if (board_technology == "XGS-PON") {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500242 device_info->set_onu_id_start(1);
243 device_info->set_onu_id_end(255);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600244 device_info->set_alloc_id_start(MIN_ALLOC_ID_XGSPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500245 device_info->set_alloc_id_end(16383);
246 device_info->set_gemport_id_start(1024);
247 device_info->set_gemport_id_end(65535);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500248 device_info->set_flow_id_start(1);
249 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500250 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000251 else if (board_technology == "GPON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500252 device_info->set_onu_id_start(1);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500253 device_info->set_onu_id_end(127);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600254 device_info->set_alloc_id_start(MIN_ALLOC_ID_GPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500255 device_info->set_alloc_id_end(767);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500256 device_info->set_gemport_id_start(256);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500257 device_info->set_gemport_id_end(4095);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500258 device_info->set_flow_id_start(1);
259 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500260 }
Craig Lutgenb2601f02018-10-23 13:04:31 -0500261
262 std::map<std::string, openolt::DeviceInfo::DeviceResourceRanges*> ranges;
263 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
264 std::string intf_technology = intf_technologies[intf_id];
265 openolt::DeviceInfo::DeviceResourceRanges *range = ranges[intf_technology];
266 if(range == nullptr) {
267 range = device_info->add_ranges();
268 ranges[intf_technology] = range;
269 range->set_technology(intf_technology);
270
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000271 if (intf_technology == "XGS-PON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500272 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
273
274 pool = range->add_pools();
275 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
276 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
277 pool->set_start(1);
278 pool->set_end(255);
279
280 pool = range->add_pools();
281 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
Girish Gowdra1d018a52020-03-05 14:38:20 -0800282 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500283 pool->set_start(1024);
284 pool->set_end(16383);
285
286 pool = range->add_pools();
287 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
Girish Gowdra1d018a52020-03-05 14:38:20 -0800288 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500289 pool->set_start(1024);
290 pool->set_end(65535);
291
292 pool = range->add_pools();
293 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
294 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
295 pool->set_start(1);
296 pool->set_end(16383);
297 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000298 else if (intf_technology == "GPON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500299 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
300
301 pool = range->add_pools();
302 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
303 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
304 pool->set_start(1);
305 pool->set_end(127);
306
307 pool = range->add_pools();
308 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
Girish Gowdra1d018a52020-03-05 14:38:20 -0800309 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500310 pool->set_start(256);
311 pool->set_end(757);
312
313 pool = range->add_pools();
314 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
Girish Gowdra1d018a52020-03-05 14:38:20 -0800315 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500316 pool->set_start(256);
317 pool->set_end(4095);
318
319 pool = range->add_pools();
320 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
321 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
322 pool->set_start(1);
323 pool->set_end(16383);
324 }
325 }
326
327 range->add_intf_ids(intf_id);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500328 }
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400329
330 // FIXME: Once dependency problem is fixed
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500331 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400332 // device_info->set_onu_id_end(XGPON_NUM_OF_ONUS - 1);
333 // device_info->set_alloc_id_start(1024);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500334 // device_info->set_alloc_id_end(XGPON_NUM_OF_ALLOC_IDS * num_of_pon_ports ? - 1);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400335 // device_info->set_gemport_id_start(XGPON_MIN_BASE_SERVICE_PORT_ID);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500336 // device_info->set_gemport_id_end(XGPON_NUM_OF_GEM_PORT_IDS_PER_PON * num_of_pon_ports ? - 1);
337 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400338
339 return Status::OK;
340}
341
Shad Ansari627b5782018-08-13 22:49:32 +0000342Status Enable_(int argc, char *argv[]) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000343 bcmos_errno err;
344 bcmolt_host_init_parms init_parms = {};
345 init_parms.transport.type = BCM_HOST_API_CONN_LOCAL;
346 unsigned int failed_enable_device_cnt = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000347
Shad Ansariedef2132018-08-10 22:14:50 +0000348 if (!state.is_activated()) {
Shad Ansari627b5782018-08-13 22:49:32 +0000349
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500350 vendor_init();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000351 /* Initialize host subsystem */
352 err = bcmolt_host_init(&init_parms);
353 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500354 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to init OLT, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000355 return bcm_to_grpc_err(err, "Failed to init OLT");
356 }
357
358 bcmcli_session_parm mon_session_parm;
359 /* Create CLI session */
360 memset(&mon_session_parm, 0, sizeof(mon_session_parm));
361 mon_session_parm.get_prompt = openolt_cli_get_prompt_cb;
362 mon_session_parm.access_right = BCMCLI_ACCESS_ADMIN;
363 bcmos_errno rc = bcmcli_session_open(&mon_session_parm, &current_session);
364 BUG_ON(rc != BCM_ERR_OK);
365
366 /* API CLI */
367 bcm_openolt_api_cli_init(NULL, current_session);
368
369 /* Add quit command */
370 BCMCLI_MAKE_CMD_NOPARM(NULL, "quit", "Quit", bcm_cli_quit);
371
372 err = bcmolt_apiend_cli_init();
373 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500374 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to add apiend init, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000375 return bcm_to_grpc_err(err, "Failed to add apiend init");
376 }
377
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800378 bcmos_fastlock_init(&data_lock, 0);
Girish Gowdra96461052019-11-22 20:13:59 +0530379 bcmos_fastlock_init(&alloc_cfg_wait_lock, 0);
Girish Gowdra7a79dae2020-02-10 18:22:11 +0530380 bcmos_fastlock_init(&onu_deactivate_wait_lock, 0);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000381 OPENOLT_LOG(INFO, openolt_log_id, "Enable OLT - %s-%s\n", VENDOR_ID, MODEL_ID);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600382
Jason Huangbf45ffb2019-10-30 17:29:02 +0800383 //check BCM daemon is connected or not
384 Status status = check_connection();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000385 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800386 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000387 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800388 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000389 Status status = SubscribeIndication();
390 if (!status.ok()) {
391 OPENOLT_LOG(ERROR, openolt_log_id, "SubscribeIndication failed - %s : %s\n",
392 grpc_status_code_to_string(status.error_code()).c_str(),
393 status.error_message().c_str());
394 return status;
395 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800396
397 //check BAL state in initial stage
398 status = check_bal_ready();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000399 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800400 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000401 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800402 }
403
404 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000405 bcmos_errno err;
406 bcmolt_odid dev;
407 OPENOLT_LOG(INFO, openolt_log_id, "Enabling PON %d Devices ... \n", BCM_MAX_DEVS_PER_LINE_CARD);
408 for (dev = 0; dev < BCM_MAX_DEVS_PER_LINE_CARD; dev++) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400409 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000410 bcmolt_device_key dev_key = { };
411 dev_key.device_id = dev;
412 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
413 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
414 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
Jason Huangbf45ffb2019-10-30 17:29:02 +0800415 if (err == BCM_ERR_NOT_CONNECTED) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000416 bcmolt_device_key key = {.device_id = dev};
417 bcmolt_device_connect oper;
418 BCMOLT_OPER_INIT(&oper, device, connect, key);
419 if (MODEL_ID == "asfvolt16") {
420 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
421 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_XGS__2_X);
422 } else if (MODEL_ID == "asgvolt64") {
423 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
424 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
425 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
426 }
427 err = bcmolt_oper_submit(dev_id, &oper.hdr);
428 if (err) {
429 failed_enable_device_cnt ++;
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500430 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 +0000431 if (failed_enable_device_cnt == BCM_MAX_DEVS_PER_LINE_CARD) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500432 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 +0000433 return Status(grpc::StatusCode::INTERNAL, "Failed to activate all PON ports");
434 }
435 }
436 bcmos_usleep(200000);
437 }
438 else {
439 OPENOLT_LOG(WARNING, openolt_log_id, "PON deivce %d already connected\n", dev);
440 state.activate();
441 }
442 }
443 init_stats();
Shad Ansari627b5782018-08-13 22:49:32 +0000444 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000445 }
Shad Ansariedef2132018-08-10 22:14:50 +0000446
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000447 /* Start CLI */
448 OPENOLT_LOG(INFO, def_log_id, "Starting CLI\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400449 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000450 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400451}
452
453Status Disable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400454 //In the earlier implementation Disabling olt is done by disabling the NNI port associated with that.
455 //In inband scenario instead of using management interface to establish connection with adapter ,NNI interface will be used.
456 //Disabling NNI port on olt disable causes connection loss between adapter and agent.
457 //To overcome this disable is implemented by disabling all the PON ports
458 //associated with the device so as to support both in-band
459 //and out of band scenarios.
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400460
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400461 Status status;
462 int failedCount = 0;
463 for (int i = 0; i < NumPonIf_(); i++) {
464 status = DisablePonIf_(i);
465 if (!status.ok()) {
466 failedCount+=1;
467 BCM_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", i);
468 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400469 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400470 if (failedCount == 0) {
471 state.deactivate();
472 openolt::Indication ind;
473 openolt::OltIndication* olt_ind = new openolt::OltIndication;
474 olt_ind->set_oper_state("down");
475 ind.set_allocated_olt_ind(olt_ind);
476 BCM_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
477 oltIndQ.push(ind);
478 return Status::OK;
479 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000480 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400481 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to disable olt ,all the PON ports are still in enabled state");
482 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400483
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400484 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 -0400485}
486
487Status Reenable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400488 Status status;
489 int failedCount = 0;
490 for (int i = 0; i < NumPonIf_(); i++) {
491 status = EnablePonIf_(i);
492 if (!status.ok()) {
493 failedCount+=1;
494 BCM_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", i);
495 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400496 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000497 if (failedCount == 0) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400498 state.activate();
499 openolt::Indication ind;
500 openolt::OltIndication* olt_ind = new openolt::OltIndication;
501 olt_ind->set_oper_state("up");
502 ind.set_allocated_olt_ind(olt_ind);
503 BCM_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
504 oltIndQ.push(ind);
505 return Status::OK;
506 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000507 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400508 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to re-enable olt ,all the PON ports are still in disabled state");
509 }
510 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 +0000511}
512
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000513inline uint64_t get_flow_status(uint16_t flow_id, uint16_t flow_type, uint16_t data_id) {
514 bcmos_errno err;
515 bcmolt_flow_key flow_key;
516 bcmolt_flow_cfg flow_cfg;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400517
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000518 flow_key.flow_id = flow_id;
519 flow_key.flow_type = (bcmolt_flow_type)flow_type;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400520
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000521 BCMOLT_CFG_INIT(&flow_cfg, flow, flow_key);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400522
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000523 switch (data_id) {
524 case ONU_ID: //onu_id
525 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, onu_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500526 #ifdef TEST_MODE
527 // It is impossible to mock the setting of flow_cfg.data.state because
528 // the actual bcmolt_cfg_get passes the address of flow_cfg.hdr and we cannot
529 // set the flow_cfg.data. So a new stub function is created and address
530 // of flow_cfg is passed. This is one-of case where we need to add test specific
531 // code in production code.
532 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
533 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000534 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500535 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000536 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500537 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get onu_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000538 return err;
539 }
540 return flow_cfg.data.onu_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400541 case FLOW_TYPE:
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500542 #ifdef TEST_MODE
543 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
544 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000545 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500546 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000547 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500548 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get flow_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000549 return err;
550 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400551 return flow_cfg.key.flow_type;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000552 case SVC_PORT_ID: //svc_port_id
553 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, svc_port_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500554 #ifdef TEST_MODE
555 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
556 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000557 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500558 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000559 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500560 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 +0000561 return err;
562 }
563 return flow_cfg.data.svc_port_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400564 case PRIORITY:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000565 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, priority);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500566 #ifdef TEST_MODE
567 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
568 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000569 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500570 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000571 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500572 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get priority, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000573 return err;
574 }
575 return flow_cfg.data.priority;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400576 case COOKIE: //cookie
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000577 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, cookie);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500578 #ifdef TEST_MODE
579 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
580 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000581 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500582 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000583 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500584 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get cookie, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000585 return err;
586 }
587 return flow_cfg.data.cookie;
588 case INGRESS_INTF_TYPE: //ingress intf_type
589 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500590 #ifdef TEST_MODE
591 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
592 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000593 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500594 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000595 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500596 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 +0000597 return err;
598 }
599 return flow_cfg.data.ingress_intf.intf_type;
600 case EGRESS_INTF_TYPE: //egress intf_type
601 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500602 #ifdef TEST_MODE
603 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
604 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000605 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500606 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000607 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500608 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 +0000609 return err;
610 }
611 return flow_cfg.data.egress_intf.intf_type;
612 case INGRESS_INTF_ID: //ingress intf_id
613 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500614 #ifdef TEST_MODE
615 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
616 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000617 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500618 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000619 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500620 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 +0000621 return err;
622 }
623 return flow_cfg.data.ingress_intf.intf_id;
624 case EGRESS_INTF_ID: //egress intf_id
625 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500626 #ifdef TEST_MODE
627 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
628 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000629 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500630 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000631 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500632 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 +0000633 return err;
634 }
635 return flow_cfg.data.egress_intf.intf_id;
636 case CLASSIFIER_O_VID:
637 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500638 #ifdef TEST_MODE
639 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
640 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000641 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500642 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000643 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500644 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 +0000645 return err;
646 }
647 return flow_cfg.data.classifier.o_vid;
648 case CLASSIFIER_O_PBITS:
649 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500650 #ifdef TEST_MODE
651 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
652 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000653 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500654 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000655 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500656 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 +0000657 return err;
658 }
659 return flow_cfg.data.classifier.o_pbits;
660 case CLASSIFIER_I_VID:
661 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500662 #ifdef TEST_MODE
663 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
664 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000665 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500666 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000667 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500668 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 +0000669 return err;
670 }
671 return flow_cfg.data.classifier.i_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400672 case CLASSIFIER_I_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000673 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500674 #ifdef TEST_MODE
675 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
676 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000677 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500678 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000679 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500680 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 +0000681 return err;
682 }
683 return flow_cfg.data.classifier.i_pbits;
684 case CLASSIFIER_ETHER_TYPE:
685 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500686 #ifdef TEST_MODE
687 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
688 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000689 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500690 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000691 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500692 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 +0000693 return err;
694 }
695 return flow_cfg.data.classifier.ether_type;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400696 case CLASSIFIER_IP_PROTO:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000697 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500698 #ifdef TEST_MODE
699 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
700 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000701 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500702 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000703 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500704 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 +0000705 return err;
706 }
707 return flow_cfg.data.classifier.ip_proto;
708 case CLASSIFIER_SRC_PORT:
709 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500710 #ifdef TEST_MODE
711 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
712 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000713 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500714 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000715 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500716 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 +0000717 return err;
718 }
719 return flow_cfg.data.classifier.src_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400720 case CLASSIFIER_DST_PORT:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000721 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500722 #ifdef TEST_MODE
723 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
724 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000725 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500726 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000727 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500728 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 +0000729 return err;
730 }
731 return flow_cfg.data.classifier.dst_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400732 case CLASSIFIER_PKT_TAG_TYPE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000733 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500734 #ifdef TEST_MODE
735 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
736 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000737 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500738 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000739 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500740 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 +0000741 return err;
742 }
743 return flow_cfg.data.classifier.pkt_tag_type;
744 case EGRESS_QOS_TYPE:
745 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500746 #ifdef TEST_MODE
747 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
748 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000749 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500750 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000751 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500752 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 +0000753 return err;
754 }
755 return flow_cfg.data.egress_qos.type;
756 case EGRESS_QOS_QUEUE_ID:
757 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500758 #ifdef TEST_MODE
759 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
760 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000761 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500762 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000763 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500764 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 +0000765 return err;
766 }
767 switch (flow_cfg.data.egress_qos.type) {
768 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE:
769 return flow_cfg.data.egress_qos.u.fixed_queue.queue_id;
770 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE:
771 return flow_cfg.data.egress_qos.u.tc_to_queue.tc_to_queue_id;
772 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC:
773 return flow_cfg.data.egress_qos.u.pbit_to_tc.tc_to_queue_id;
774 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE:
775 return flow_cfg.data.egress_qos.u.priority_to_queue.tm_q_set_id;
776 case BCMOLT_EGRESS_QOS_TYPE_NONE:
777 default:
778 return -1;
779 }
780 case EGRESS_QOS_TM_SCHED_ID:
781 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500782 #ifdef TEST_MODE
783 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
784 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000785 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500786 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000787 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500788 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 +0000789 return err;
790 }
791 return flow_cfg.data.egress_qos.tm_sched.id;
792 case ACTION_CMDS_BITMASK:
793 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500794 #ifdef TEST_MODE
795 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
796 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000797 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500798 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000799 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500800 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 +0000801 return err;
802 }
803 return flow_cfg.data.action.cmds_bitmask;
804 case ACTION_O_VID:
805 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500806 #ifdef TEST_MODE
807 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
808 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000809 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500810 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000811 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500812 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 +0000813 return err;
814 }
815 return flow_cfg.data.action.o_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400816 case ACTION_O_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000817 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500818 #ifdef TEST_MODE
819 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
820 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000821 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500822 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000823 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500824 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 +0000825 return err;
826 }
827 return flow_cfg.data.action.o_pbits;
828 case ACTION_I_VID:
829 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500830 #ifdef TEST_MODE
831 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
832 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000833 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500834 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000835 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500836 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 +0000837 return err;
838 }
839 return flow_cfg.data.action.i_vid;
840 case ACTION_I_PBITS:
841 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500842 #ifdef TEST_MODE
843 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
844 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000845 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500846 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000847 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500848 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 +0000849 return err;
850 }
851 return flow_cfg.data.action.i_pbits;
852 case STATE:
853 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, state);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500854 #ifdef TEST_MODE
855 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
856 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000857 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500858 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000859 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500860 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get state, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000861 return err;
862 }
863 return flow_cfg.data.state;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000864 case GROUP_ID:
865 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, group_id);
866 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
867 if (err) {
868 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get group_id, err = %s\n",bcmos_strerror(err));
869 return err;
870 }
871 return flow_cfg.data.group_id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000872 default:
873 return BCM_ERR_INTERNAL;
874 }
875
876 return err;
877}
878
879Status EnablePonIf_(uint32_t intf_id) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400880 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000881 bcmolt_pon_interface_cfg interface_obj;
882 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
883 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
884 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530885 bcmolt_status los_status;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000886
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530887 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000888 if (err == BCM_ERR_OK) {
889 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800890 OPENOLT_LOG(WARNING, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000891 return Status::OK;
892 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400893 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000894 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
895 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
896 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
897 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.interval, 5000);
898 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.onu_post_discovery_mode,
Girish Gowdra24297032020-03-23 12:32:37 -0700899 BCMOLT_ONU_POST_DISCOVERY_MODE_NONE);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000900 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.los, true);
901 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.onu_alarms, true);
902 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.tiwi, true);
903 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.ack_timeout, true);
904 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.sfi, true);
905 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.loki, true);
Burak Gurdag5e587792020-05-06 14:58:02 +0000906
907 // On GPON, power level mode is not set to its default value (i.e. 0) as documented in Broadcom documentation.
908 // Instead, it is set to 2 which means -6 dbM attenuation. Therefore, we explicitly set it to the default value below.
909 if (board_technology == "GPON") {
910 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.pls_maximum_allocation_size, BCMOLT_PON_POWER_LEVEL_PLS_MAXIMUM_ALLOCATION_SIZE_DEFAULT);
911 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.mode, BCMOLT_PON_POWER_LEVEL_MODE_DEFAULT);
912 }
913
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000914 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
915 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
916
917 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
918 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500919 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 +0000920 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
921 }
922 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
923 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500924 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 +0000925 return bcm_to_grpc_err(err, "Failed to enable PON interface");
926 }
927 else {
928 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
929 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
930 CreateDefaultSched(intf_id, downstream);
931 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400932 }
933
934 return Status::OK;
935}
936
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500937Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000938 bcmos_errno err;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400939 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000940 bcmolt_device_key dev_key = { };
941 bcmolt_olt_cfg olt_cfg = { };
942 bcmolt_olt_key olt_key = { };
943 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
944 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500945
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000946 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
947 topo.topology_maps.arr = &topo_map[0];
948 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
949 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
950 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400951 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000952 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400953 #ifdef TEST_MODE
954 // It is impossible to mock the setting of olt_cfg.data.bal_state because
955 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
956 // set the olt_cfg.data.topology. So a new stub function is created and address
957 // of olt_cfg is passed. This is one-of case where we need to test add specific
958 // code in production code.
959 err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
960 #else
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000961 err = bcmolt_cfg_get_mult_retry(dev_id, &olt_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400962 #endif
963 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500964 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 +0000965 return bcm_to_grpc_err(err, "cfg: Failed to query OLT topology");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500966 }
967
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000968 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
969 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500970
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400971 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
972 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000973 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500974
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000975 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
976 num_of_nni_ports,
977 num_of_pon_ports,
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400978 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500979
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000980 uint32_t num_failed_cfg_gets = 0;
Jason Huang09b73ea2020-01-08 17:52:05 +0800981 static std::string openolt_version = firmware_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000982 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
983 dev_key.device_id = devid;
984 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
985 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
986 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
987 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000988 err = bcmolt_cfg_get_mult_retry(dev_id, &dev_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400989 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500990 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 +0000991 num_failed_cfg_gets++;
992 continue;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000993 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500994
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000995 std::string bal_version;
996 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
997 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
998 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
Jason Huang09b73ea2020-01-08 17:52:05 +0800999 firmware_version = "BAL." + bal_version + "__" + openolt_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001000
1001 switch(dev_cfg.data.system_mode) {
1002 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
1003 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
1004 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
1005 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
1006 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
1007 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
1008 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
1009 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
1010 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
1011 case 20: board_technology = MIXED_TECH; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,MIXED_TECH); break;
1012 }
1013
1014 switch(dev_cfg.data.chip_family) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001015 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X: chip_family = "Maple"; break;
1016 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X: chip_family = "Aspen"; break;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001017 }
1018
Jason Huang09b73ea2020-01-08 17:52:05 +08001019 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s, family: %s, board_technology: %s\n",
1020 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 +00001021
1022 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001023 }
1024
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001025 /* 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 +00001026 only the devices that retured success*/
1027 if (num_failed_cfg_gets == BCM_MAX_DEVS_PER_LINE_CARD) {
1028 OPENOLT_LOG(ERROR, openolt_log_id, "device: Query of all the devices failed\n");
1029 return bcm_to_grpc_err(err, "device: All devices failed query");
1030 }
1031
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001032 return Status::OK;
1033}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001034
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001035Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001036 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001037 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
1038 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
1039 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001040
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001041 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001042 if (err == BCM_ERR_OK) {
1043 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001044 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001045 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1046 CreateDefaultSched(intf_id, upstream);
1047 CreateDefaultQueue(intf_id, upstream);
1048 return Status::OK;
1049 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1050 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
1051 return Status::OK;
1052 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001053 }
1054
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001055 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
1056 if (set_state) {
1057 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1058 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1059 } else {
1060 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1061 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1062 }
1063 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
1064 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001065 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err = %s\n",
1066 (set_state)?"enable":"disable", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001067 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
1068 }
1069 else {
1070 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
1071 if (set_state) {
1072 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1073 CreateDefaultSched(intf_id, upstream);
1074 CreateDefaultQueue(intf_id, upstream);
1075 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001076 }
1077
1078 return Status::OK;
1079}
1080
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001081Status DisablePonIf_(uint32_t intf_id) {
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001082 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001083 bcmolt_pon_interface_cfg interface_obj;
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001084 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1085 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001086
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001087 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
1088 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1089 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_DISABLE);
1090
1091 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1092 if (err != BCM_ERR_OK) {
1093 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable discovery of onu, PON interface %d, err %d\n", intf_id, err);
1094 return bcm_to_grpc_err(err, "Failed to disable discovery of onu");
1095 }
1096
1097 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1098 operation, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1099
1100 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1101 if (err != BCM_ERR_OK) {
1102 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 -04001103 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001104 }
1105
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001106 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled PON interface: %d\n", intf_id);
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001107 return Status::OK;
1108}
1109
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001110Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001111 const char *vendor_id, const char *vendor_specific, uint32_t pir) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001112 bcmos_errno err = BCM_ERR_OK;
1113 bcmolt_onu_cfg onu_cfg;
1114 bcmolt_onu_key onu_key;
1115 bcmolt_serial_number serial_number; /**< ONU serial number */
1116 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001117
Girish Gowdra24297032020-03-23 12:32:37 -07001118 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1119 bcmolt_onu_state onu_state;
1120
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001121 onu_key.onu_id = onu_id;
1122 onu_key.pon_ni = intf_id;
1123 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1124 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Girish Gowdra24297032020-03-23 12:32:37 -07001125#ifdef TEST_MODE
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001126 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1127 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1128 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1129 // of onu_cfg is passed. This is one-of case where we need to add test specific
1130 // code in production code.
1131 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Girish Gowdra24297032020-03-23 12:32:37 -07001132#else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001133 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Girish Gowdra24297032020-03-23 12:32:37 -07001134#endif
1135 OPENOLT_LOG(INFO, openolt_log_id, "Activate ONU : old state = %d, current state = %d\n",
1136 onu_cfg.data.onu_old_state, onu_cfg.data.onu_state);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001137 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001138 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) {
1139 OPENOLT_LOG(INFO, openolt_log_id, "ONU is already in ACTIVE state, \
1140not processing this request for pon_intf=%d onu_id=%d\n", intf_id, onu_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001141 return Status::OK;
Girish Gowdra24297032020-03-23 12:32:37 -07001142 } else if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_NOT_CONFIGURED &&
1143 onu_cfg.data.onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1144 // We need the ONU to be in NOT_CONFIGURED or INACTIVE state to further process the request
1145 OPENOLT_LOG(ERROR, openolt_log_id, "ONU in an invalid state to process the request, \
1146state=%d pon_intf=%d onu_id=%d\n", onu_cfg.data.onu_state, intf_id, onu_id);
1147 return bcm_to_grpc_err(err, "Failed to activate ONU, invalid ONU state");
1148 }
1149 } else {
1150 // This should never happen. BAL GET should succeed for non-existant ONUs too. The state of such ONUs will be NOT_CONFIGURED
1151 OPENOLT_LOG(ERROR, openolt_log_id, "ONU state query failed pon_intf=%d onu_id=%d\n", intf_id, onu_id);
1152 return bcm_to_grpc_err(err, "onu get failed");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001153 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001154
Girish Gowdra24297032020-03-23 12:32:37 -07001155 // If the ONU is not configured at all we need to first configure it
1156 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_NOT_CONFIGURED) {
1157 OPENOLT_LOG(INFO, openolt_log_id, "Configuring ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001158vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Girish Gowdra24297032020-03-23 12:32:37 -07001159 vendor_specific_to_str(vendor_specific).c_str(), pir);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001160
Girish Gowdra24297032020-03-23 12:32:37 -07001161 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1162 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1163 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1164 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1165 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1166 /*set burst and data profiles to fec disabled*/
1167 if (board_technology == "XGS-PON") {
1168 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1169 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1170 } else if (board_technology == "GPON") {
1171 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1172 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1173 }
1174 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1175 if (err != BCM_ERR_OK) {
1176 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to configure ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
1177 return bcm_to_grpc_err(err, "Failed to configure ONU");
1178 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001179 }
Girish Gowdra24297032020-03-23 12:32:37 -07001180
1181 // Now that the ONU is configured, move the ONU to ACTIVE state
1182 memset(&onu_cfg, 0, sizeof(bcmolt_onu_cfg));
1183 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1184 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1185 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
1186 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
1187 onu_state, BCMOLT_ONU_OPERATION_ACTIVE);
1188 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001189 if (err != BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001190 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 +00001191 return bcm_to_grpc_err(err, "Failed to activate ONU");
1192 }
Girish Gowdra24297032020-03-23 12:32:37 -07001193 // ONU will eventually get activated after we have submitted the operation request. The adapter will receive an asynchronous
1194 // ONU_ACTIVATION_COMPLETED_INDICATION
1195
1196 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 +00001197
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001198 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001199}
1200
Jonathan Davis70c21812018-07-19 15:32:10 -04001201Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1202 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001203 bcmos_errno err = BCM_ERR_OK;
1204 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1205 bcmolt_onu_cfg onu_cfg;
1206 bcmolt_onu_key onu_key; /**< Object key. */
1207 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001208
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001209 onu_key.onu_id = onu_id;
1210 onu_key.pon_ni = intf_id;
1211 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1212 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001213 #ifdef TEST_MODE
1214 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1215 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1216 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1217 // of onu_cfg is passed. This is one-of case where we need to add test specific
1218 // code in production code.
1219 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001220 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001221 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001222 #endif
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301223 onu_state = onu_cfg.data.onu_state;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001224 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001225 switch (onu_state) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001226 case BCMOLT_ONU_STATE_ACTIVE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001227 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001228 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001229 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1230 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1231 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001232 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 +00001233 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1234 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301235 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 +00001236 break;
1237 }
Jonathan Davis70c21812018-07-19 15:32:10 -04001238 }
1239
1240 return Status::OK;
1241}
1242
1243Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001244 const char *vendor_id, const char *vendor_specific) {
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301245 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301246 bcmolt_onu_state onu_state;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001247
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001248 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 -05001249 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1250
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001251 // Need to deactivate before removing it (BAL rules)
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001252 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301253
1254 err = get_onu_status((bcmolt_interface)intf_id, onu_id, &onu_state);
1255 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001256 if (onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1257 OPENOLT_LOG(INFO, openolt_log_id, "waiting for onu deactivate complete response: intf_id=%d, onu_id=%d\n",
1258 intf_id, onu_id);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301259 err = wait_for_onu_deactivate_complete(intf_id, onu_id);
1260 if (err) {
1261 OPENOLT_LOG(ERROR, openolt_log_id, "failed to delete onu intf_id %d, onu_id %d\n",
1262 intf_id, onu_id);
1263 return bcm_to_grpc_err(err, "Failed to delete ONU");
1264 }
1265 }
Girish Gowdra24297032020-03-23 12:32:37 -07001266 else {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301267 OPENOLT_LOG(INFO, openolt_log_id, "Onu is Inactive, onu_id: %d, not waiting for onu deactivate complete response\n",
1268 intf_id);
1269 }
1270 }
1271 else {
1272 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch Onu status, onu_id = %d, intf_id = %d, err = %s\n",
1273 onu_id, intf_id, bcmos_strerror(err));
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301274 return bcm_to_grpc_err(err, "Failed to delete ONU");
1275 }
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001276
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001277 bcmolt_onu_cfg cfg_obj;
1278 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001279
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001280 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 -04001281 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001282
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001283 key.onu_id = onu_id;
1284 key.pon_ni = intf_id;
1285 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001286
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301287 err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001288 if (err != BCM_ERR_OK)
1289 {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001290 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 -04001291 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1292 }
1293
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301294 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 +00001295 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001296}
1297
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001298#define MAX_CHAR_LENGTH 20
1299#define MAX_OMCI_MSG_LENGTH 44
1300Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001301 bcmolt_bin_str buf = {};
1302 bcmolt_onu_cpu_packets omci_cpu_packets;
1303 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001304
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001305 key.pon_ni = intf_id;
1306 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001307
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001308 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1309 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1310 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001311
1312 // ???
1313 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1314 buf.len = MAX_OMCI_MSG_LENGTH;
1315 } else {
1316 buf.len = pkt.size()/2;
1317 }
1318
1319 /* Send the OMCI packet using the BAL remote proxy API */
1320 uint16_t idx1 = 0;
1321 uint16_t idx2 = 0;
1322 uint8_t arraySend[buf.len];
1323 char str1[MAX_CHAR_LENGTH];
1324 char str2[MAX_CHAR_LENGTH];
1325 memset(&arraySend, 0, buf.len);
1326
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001327 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1328 sprintf(str1,"%c", pkt[idx1]);
1329 sprintf(str2,"%c", pkt[++idx1]);
1330 strcat(str1,str2);
1331 arraySend[idx2] = strtol(str1, NULL, 16);
1332 }
1333
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001334 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1335 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001336
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001337 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1338 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1339 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001340
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001341 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001342 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001343 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 +00001344 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001345 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001346 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 -05001347 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001348 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001349 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001350
1351 return Status::OK;
1352}
1353
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001354Status 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 +00001355 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1356 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1357 bcmolt_bin_str buf = {};
1358 bcmolt_gem_port_id gem_port_id_array[1];
1359 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001360
Craig Lutgen967a1d02018-11-27 10:41:51 -06001361 if (port_no > 0) {
1362 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001363 if (gemport_id == 0) {
1364 bcmos_fastlock_lock(&data_lock);
1365 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1366 // Pick any flow that is mapped with the same port_no.
1367 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1368 if (it != port_to_flows.end() && !it->second.empty()) {
1369 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1370 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1371 if (fit != flowid_to_gemport.end()) {
1372 found = true;
1373 gemport_id = fit->second;
1374 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001375 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001376 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001377
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001378 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001379 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 -08001380 onu_id, port_no, intf_id);
1381 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1382 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001383 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 -08001384 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001385 }
1386
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001387 gem_port_id_array[0] = gemport_id;
1388 gem_port_list.len = 1;
1389 gem_port_list.arr = gem_port_id_array;
1390 buf.len = pkt.size();
1391 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1392 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1393
1394 /* init the API struct */
1395 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1396 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1397 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1398 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1399 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1400
1401 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1402 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1403
1404 /* call API */
1405 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001406 }
1407 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001408 //TODO: Port No is 0, it is coming sender requirement.
1409 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1410 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001411 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001412 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001413
1414 return Status::OK;
1415}
1416
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001417Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001418 bcmolt_flow_key key = {}; /* declare key */
1419 bcmolt_bin_str buffer = {};
1420 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001421
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001422 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
1423 bcmolt_flow_id flow_id = 0;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001424
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001425 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1426 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1427 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1428 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1429 key.flow_id = flow_id;
1430 else {
Jason Huang09b73ea2020-01-08 17:52:05 +08001431 if (flow_id_counters) {
1432 std::map<flow_pair, int>::iterator it;
1433 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1434 int flow_index = it->first.first;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001435 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1436 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1437 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1438 key.flow_id = flow_index;
1439 break;
1440 }
1441 }
1442 }
1443 else {
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001444 OPENOLT_LOG(ERROR, openolt_log_id, "no flow id found for uplink packetout\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001445 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1446 }
1447 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001448
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001449 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001450
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001451 /* Initialize the API struct. */
1452 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001453
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001454 buffer.len = pkt.size();
1455 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1456 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1457 if (buffer.arr == NULL) {
1458 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1459 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1460 }
1461 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1462
1463 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1464 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001465 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 -05001466 return bcm_to_grpc_err(BCM_ERR_SYSCALL_ERR, "Error sending packets via nni port");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001467 } else {
1468 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1469 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001470
1471 return Status::OK;
1472}
Craig Lutgen967a1d02018-11-27 10:41:51 -06001473Status 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 +00001474 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001475 int32_t alloc_id, int32_t network_intf_id,
1476 int32_t gemport_id, const ::openolt::Classifier& classifier,
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001477 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00001478 int32_t group_id, uint32_t tech_profile_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001479 bcmolt_flow_cfg cfg;
1480 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001481 int32_t o_vid = -1;
1482 bool single_tag = false;
1483 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001484 bcmolt_classifier c_val = { };
1485 bcmolt_action a_val = { };
1486 bcmolt_tm_queue_ref tm_val = { };
1487 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05001488 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001489
Jason Huang09b73ea2020-01-08 17:52:05 +08001490 OPENOLT_LOG(INFO, openolt_log_id, "flow add received for flow_id=%u, flow_type=%s\n", flow_id, flow_type.c_str());
1491
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001492 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001493 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001494 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001495 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001496 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001497 } else if (flow_type.compare(multicast) == 0) {
1498 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001499 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001500 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001501 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001502 }
1503
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001504 BCMOLT_CFG_INIT(&cfg, flow, key);
1505 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001506
Jason Huang09b73ea2020-01-08 17:52:05 +08001507 if (action.cmd().trap_to_host()) {
1508 Status resp = handle_acl_rule_install(onu_id, flow_id, flow_type, access_intf_id,
1509 network_intf_id, gemport_id, classifier);
1510 return resp;
1511 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001512
1513 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1514
1515 if (access_intf_id >= 0 && network_intf_id >= 0) {
1516 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1517 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1518 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08001519 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1520 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001521 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1522 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1523 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1524 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1525 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001526 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001527 } else {
1528 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
1529 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001530 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001531
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001532 if (onu_id >= 0) {
1533 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
1534 }
1535 if (gemport_id >= 0) {
1536 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
1537 }
1538 if (gemport_id >= 0 && port_no != 0) {
1539 bcmos_fastlock_lock(&data_lock);
1540 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
1541 port_to_flows[port_no].insert(key.flow_id);
1542 flowid_to_gemport[key.flow_id] = gemport_id;
1543 }
1544 else
1545 {
1546 flowid_to_port[key.flow_id] = port_no;
1547 }
1548 bcmos_fastlock_unlock(&data_lock, 0);
1549 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001550 if (gemport_id >= 0 && access_intf_id >= 0) {
1551 // Update the flow_to_acl_map. Note that since this is a datapath flow, acl_id is -1
1552 // This info is needed during flow remove where we need to retrieve the gemport_id
1553 // and access_intf id for the given flow id and flow direction.
1554 // After retrieving the ACL ID and GEM PORT ID, we decrement the corresponding
1555 // reference counters for those ACL ID and GEMPORT ID.
1556 acl_id_gem_id_intf_id ac_id_gm_id_if_id(-1, gemport_id, access_intf_id);
1557 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
1558 bcmos_fastlock_lock(&data_lock);
1559 flow_to_acl_map[fl_id_fl_dir] = ac_id_gm_id_if_id;
1560 bcmos_fastlock_unlock(&data_lock, 0);
1561 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001562 if (priority_value >= 0) {
1563 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
1564 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301565
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001566 } else { // MULTICAST FLOW
1567 if (group_id >= 0) {
1568 BCMOLT_MSG_FIELD_SET(&cfg, group_id, group_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001569 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001570 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1571 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001572 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001573
1574 {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001575 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001576 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001577 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
1578 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001579 }
1580
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001581 if (classifier.dst_mac().size() > 0) {
1582 bcmos_mac_address d_mac = {};
1583 bcmos_mac_address_init(&d_mac);
1584 memcpy(d_mac.u8, classifier.dst_mac().data(), sizeof(d_mac.u8));
1585 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_mac %02x:%02x:%02x:%02x:%02x:%02x\n", d_mac.u8[0],
1586 d_mac.u8[1], d_mac.u8[2], d_mac.u8[3], d_mac.u8[4], d_mac.u8[5]);
1587 BCMOLT_FIELD_SET(&c_val, classifier, dst_mac, d_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001588 }
1589
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001590 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001591 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001592 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001593 }
1594 */
1595
1596 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001597 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
1598 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001599 }
1600
1601 /*
1602 if (classifier.dst_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001603 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_ip, classifier.dst_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001604 }
1605
1606 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001607 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001608 }
1609 */
1610
1611 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001612 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
1613 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001614 }
1615
1616 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001617 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
1618 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001619 }
1620
1621 if (!classifier.pkt_tag_type().empty()) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001622 if (classifier.o_vid()) {
1623 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
1624 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
1625 }
1626
1627 if (classifier.i_vid()) {
1628 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
1629 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
1630 }
1631
1632 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
1633 if (classifier.pkt_tag_type().compare("untagged") == 0) {
1634 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
1635 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
1636 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
1637 single_tag = true;
1638
1639 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301640 // OpenOlt adapter will send 0xFF in case of no pbit classification
1641 // If it is any other value (0 to 7), it is for outer pbit classification.
1642 // OpenFlow protocol does not provide inner pbit classification (in case of double tagged packets),
1643 // and VOLTHA has not used any workaround to solve this problem (for ex: use metadata field).
1644 // Also there exists no use case for i-pbit classification, so we can safely ignore this for now.
1645 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001646 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301647 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001648 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
1649 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001650
Jason Huang09b73ea2020-01-08 17:52:05 +08001651 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301652 // Same comments as in case of "single_tag" packets.
1653 // 0xFF means no pbit classification, otherwise a valid PCP (0 to 7).
1654 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001655 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301656 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001657 }
1658 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001659 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001660 }
1661
Jason Huang09b73ea2020-01-08 17:52:05 +08001662 const ::openolt::ActionCmd& cmd = action.cmd();
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001663
Jason Huang09b73ea2020-01-08 17:52:05 +08001664 if (cmd.add_outer_tag()) {
1665 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
1666 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001667 }
1668
Jason Huang09b73ea2020-01-08 17:52:05 +08001669 if (cmd.remove_outer_tag()) {
1670 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
1671 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
1672 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301673
Jason Huang09b73ea2020-01-08 17:52:05 +08001674 if (action.o_vid()) {
1675 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
1676 o_vid = action.o_vid();
1677 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
1678 }
1679
1680 if (action.o_pbits()) {
1681 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
1682 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
1683 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301684
Jason Huang09b73ea2020-01-08 17:52:05 +08001685 if (action.i_vid()) {
1686 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
1687 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
1688 }
1689
1690 if (action.i_pbits()) {
1691 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
1692 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
1693 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301694
Jason Huang09b73ea2020-01-08 17:52:05 +08001695 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
1696
Shad Ansari39739bc2018-09-13 21:38:37 +00001697 if ((access_intf_id >= 0) && (onu_id >= 0)) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001698 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
1699 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00001700 tm_val.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, downstream, tech_profile_id);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001701
Jason Huang09b73ea2020-01-08 17:52:05 +08001702 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1703 // Queue 0 on DS subscriber scheduler
1704 tm_val.queue_id = 0;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001705
Jason Huang09b73ea2020-01-08 17:52:05 +08001706 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1707 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1708 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001709
Jason Huang09b73ea2020-01-08 17:52:05 +08001710 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1711 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1712 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001713
Jason Huang09b73ea2020-01-08 17:52:05 +08001714 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1715 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
1716 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 +00001717
Jason Huang09b73ea2020-01-08 17:52:05 +08001718 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1719 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1720 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1721 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 +00001722
Jason Huang09b73ea2020-01-08 17:52:05 +08001723 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
1724 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1725 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1726 }
1727 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
1728 // NNI Scheduler ID
1729 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1730 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1731 // Queue 0 on NNI scheduler
1732 tm_val.queue_id = 0;
1733 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1734 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1735 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001736
Jason Huang09b73ea2020-01-08 17:52:05 +08001737 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 +00001738 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1739 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1740
Jason Huang09b73ea2020-01-08 17:52:05 +08001741 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1742 /* Fetch TM QMP ID mapped to US NNI scheduler */
1743 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
1744 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1745 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1746 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1747 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 +00001748
Jason Huang09b73ea2020-01-08 17:52:05 +08001749 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 +00001750 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1751 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001752 }
Shad Ansari39739bc2018-09-13 21:38:37 +00001753 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301754 } else {
1755 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1756 tm_val.queue_id = 0;
1757
1758 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
1759 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1760 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
1761
1762 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1763 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
1764 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00001765 }
1766
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001767 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001768
1769 // BAL 3.1 supports statistics only for unicast flows.
1770 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1771 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
1772 }
1773
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001774#ifdef FLOW_CHECKER
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001775 //Flow Checker, To avoid duplicate flow.
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001776 if (flow_id_counters != 0) {
1777 bool b_duplicate_flow = false;
Jason Huang09b73ea2020-01-08 17:52:05 +08001778 std::map<flow_pair, int>::iterator it;
1779
1780 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1781 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(it->first.first, it->first.second, ONU_ID)) && \
1782 (key.flow_type == it->first.second) && \
1783 (cfg.data.svc_port_id == get_flow_status(it->first.first, it->first.second, SVC_PORT_ID)) && \
1784 (cfg.data.priority == get_flow_status(it->first.first, it->first.second, PRIORITY)) && \
1785 (cfg.data.cookie == get_flow_status(it->first.first, it->first.second, COOKIE)) && \
1786 (cfg.data.ingress_intf.intf_type == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_TYPE)) && \
1787 (cfg.data.ingress_intf.intf_id == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_ID)) && \
1788 (cfg.data.egress_intf.intf_type == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_TYPE)) && \
1789 (cfg.data.egress_intf.intf_id == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_ID)) && \
1790 (c_val.o_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_VID)) && \
1791 (c_val.o_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_PBITS)) && \
1792 (c_val.i_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_VID)) && \
1793 (c_val.i_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_PBITS)) && \
1794 (c_val.ether_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_ETHER_TYPE)) && \
1795 (c_val.ip_proto == get_flow_status(it->first.first, it->first.second, CLASSIFIER_IP_PROTO)) && \
1796 (c_val.src_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_SRC_PORT)) && \
1797 (c_val.dst_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_DST_PORT)) && \
1798 (c_val.pkt_tag_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_PKT_TAG_TYPE)) && \
1799 (cfg.data.egress_qos.type == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TYPE)) && \
1800 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_QUEUE_ID)) && \
1801 (cfg.data.egress_qos.tm_sched.id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TM_SCHED_ID)) && \
1802 (a_val.cmds_bitmask == get_flow_status(it->first.first, it->first.second, ACTION_CMDS_BITMASK)) && \
1803 (a_val.o_vid == get_flow_status(it->first.first, it->first.second, ACTION_O_VID)) && \
1804 (a_val.i_vid == get_flow_status(it->first.first, it->first.second, ACTION_I_VID)) && \
1805 (a_val.o_pbits == get_flow_status(it->first.first, it->first.second, ACTION_O_PBITS)) && \
1806 (a_val.i_pbits == get_flow_status(it->first.first, it->first.second, ACTION_I_PBITS)) && \
1807 (cfg.data.state == get_flow_status(it->first.first, it->first.second, STATE)) && \
1808 (cfg.data.group_id == get_flow_status(it->first.first, it->first.second, GROUP_ID));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001809#ifdef SHOW_FLOW_PARAM
1810 // Flow Parameter
1811 FLOW_PARAM_LOG();
1812#endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001813 if (b_duplicate_flow) {
1814 FLOW_LOG(WARNING, "Flow duplicate", 0);
1815 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
1816 }
1817 }
1818 }
1819#endif
1820
1821 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
1822 if (err) {
1823 FLOW_LOG(ERROR, "Flow add failed", err);
1824 return bcm_to_grpc_err(err, "flow add failed");
1825 } else {
1826 FLOW_LOG(INFO, "Flow add ok", err);
1827 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08001828 flow_map[std::pair<int, int>(key.flow_id,key.flow_type)] = flow_map.size();
1829 flow_id_counters = flow_map.size();
1830 if (gemport_id > 0 && access_intf_id >= 0) {
1831 gem_id_intf_id gem_intf(gemport_id, access_intf_id);
1832 if (gem_ref_cnt.count(gem_intf) > 0) {
1833 // The gem port is already installed
1834 // Increment the ref counter indicating number of flows referencing this gem port
1835 gem_ref_cnt[gem_intf]++;
1836 OPENOLT_LOG(DEBUG, openolt_log_id, "incremented gem_ref_cnt, gem_ref_cnt=%d\n", gem_ref_cnt[gem_intf]);
1837 } else {
1838 // Initialize the refence count for the gemport.
1839 gem_ref_cnt[gem_intf] = 1;
1840 OPENOLT_LOG(DEBUG, openolt_log_id, "initialized gem_ref_cnt\n");
1841 }
1842 } else {
1843 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);
1844 }
1845
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001846 bcmos_fastlock_unlock(&data_lock, 0);
1847 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04001848
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001849 return Status::OK;
1850}
1851
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001852Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
1853
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001854 bcmolt_flow_cfg cfg;
1855 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001856
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001857 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001858 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001859 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001860 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001861 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001862 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001863 } else if(flow_type.compare(multicast) == 0) {
1864 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001865 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001866 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001867 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
1868 }
1869
Jason Huang09b73ea2020-01-08 17:52:05 +08001870 OPENOLT_LOG(INFO, openolt_log_id, "flow remove received for flow_id=%u, flow_type=%s\n",
1871 flow_id, flow_type.c_str());
1872
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001873 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08001874 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
1875 int32_t gemport_id = -1;
1876 int32_t intf_id = -1;
1877 int16_t acl_id = -1;
1878 if (flow_to_acl_map.count(fl_id_fl_dir) > 0) {
1879 acl_id_gem_id_intf_id ac_id_gm_id_if_id = flow_to_acl_map[fl_id_fl_dir];
1880 acl_id = std::get<0>(ac_id_gm_id_if_id);
1881 gemport_id = std::get<1>(ac_id_gm_id_if_id);
1882 intf_id = std::get<2>(ac_id_gm_id_if_id);
1883 // cleanup acl only if it is a valid acl. If not valid acl, it may be datapath flow.
1884 if (acl_id >= 0) {
1885 Status resp = handle_acl_rule_cleanup(acl_id, gemport_id, intf_id, flow_type);
1886 bcmos_fastlock_unlock(&data_lock, 0);
1887 if (resp.ok()) {
1888 OPENOLT_LOG(INFO, openolt_log_id, "acl removed ok for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
1889 flow_to_acl_map.erase(fl_id_fl_dir);
1890 } else {
1891 OPENOLT_LOG(ERROR, openolt_log_id, "acl remove error for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
1892 }
1893 return resp;
1894 }
1895 }
1896
Craig Lutgen967a1d02018-11-27 10:41:51 -06001897 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001898 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06001899 flowid_to_gemport.erase(key.flow_id);
1900 port_to_flows[port_no].erase(key.flow_id);
1901 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
1902 }
1903 else
1904 {
1905 flowid_to_port.erase(key.flow_id);
1906 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001907 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001908
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001909 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001910
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001911 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001912 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001913 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 -04001914 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
1915 }
1916
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001917 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08001918 if (flow_id_counters != 0) {
1919 std::map<flow_pair, int>::iterator it;
1920 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1921 if (it->first.first == flow_id && it->first.second == key.flow_type) {
1922 flow_id_counters -= 1;
1923 flow_map.erase(it);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001924 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001925 }
1926 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001927 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
1928
1929 clear_gem_port(gemport_id, intf_id);
1930
1931 flow_to_acl_map.erase(fl_id_fl_dir);
1932
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001933 bcmos_fastlock_unlock(&data_lock, 0);
1934
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001935 return Status::OK;
1936}
1937
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001938bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
1939 bcmos_errno err;
1940 bcmolt_tm_sched_cfg tm_sched_cfg;
1941 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
1942 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
1943
Jason Huangbf45ffb2019-10-30 17:29:02 +08001944 //check TM scheduler has configured or not
1945 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
1946 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001947 #ifdef TEST_MODE
1948 // It is impossible to mock the setting of tm_sched_cfg.data.state because
1949 // the actual bcmolt_cfg_get passes the address of tm_sched_cfg.hdr and we cannot
1950 // set the tm_sched_cfg.data.state. So a new stub function is created and address
1951 // of tm_sched_cfg is passed. This is one-of case where we need to add test specific
1952 // code in production code.
1953 err = bcmolt_cfg_get__tm_sched_stub(dev_id, &tm_sched_cfg);
1954 #else
Jason Huangbf45ffb2019-10-30 17:29:02 +08001955 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001956 #endif
Jason Huangbf45ffb2019-10-30 17:29:02 +08001957 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001958 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 +08001959 return err;
1960 }
1961 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
1962 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
1963 return BCM_ERR_OK;
1964 }
1965
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001966 // bcmbal_tm_sched_owner
1967 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
1968
1969 /**< The output of the tm_sched object instance */
1970 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
1971
1972 if (direction.compare(upstream) == 0) {
1973 // In upstream it is NNI scheduler
1974 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
1975 } else if (direction.compare(downstream) == 0) {
1976 // In downstream it is PON scheduler
1977 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
1978 }
1979
1980 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
1981
1982 // bcmbal_tm_sched_type
1983 // set the deafult policy to strict priority
1984 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
1985
1986 // num_priorities: Max number of strict priority scheduling elements
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001987 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, NUM_OF_PRIORITIES);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001988
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001989 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
1990 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001991 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
1992 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001993 return err;
1994 }
1995
1996 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
1997 direction.c_str(), tm_sched_key.id, intf_id);
1998 return BCM_ERR_OK;
1999}
2000
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002001bcmos_errno CreateSched(std::string direction, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t port_no,
2002 uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002003 tech_profile::SchedulingPolicy sched_policy, tech_profile::TrafficShapingInfo tf_sh_info,
2004 uint32_t tech_profile_id) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002005
2006 bcmos_errno err;
2007
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002008 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002009 bcmolt_tm_sched_cfg tm_sched_cfg;
2010 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002011 tm_sched_key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002012
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002013 // bcmbal_tm_sched_owner
2014 // In downstream it is sub_term scheduler
2015 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002016
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002017 /**< The output of the tm_sched object instance */
2018 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002019
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002020 // bcmbal_tm_sched_parent
2021 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2022 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
2023 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 +00002024 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002025 be achieved using the' virtual' type of attachment.
2026 tm_sched_owner.u.sub_term.intf_id = intf_id;
2027 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2028 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002029
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002030 // bcmbal_tm_sched_type
2031 // set the deafult policy to strict priority
2032 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002033
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002034 // num_priorities: Max number of strict priority scheduling elements
2035 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002036
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002037 // bcmbal_tm_shaping
2038 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2039 uint32_t cir = tf_sh_info.cir();
2040 uint32_t pir = tf_sh_info.pir();
2041 uint32_t burst = tf_sh_info.pbs();
2042 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2043 cir, pir, burst);
2044 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2045 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2046 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2047 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2048 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2049 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002050 }
2051
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002052 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002053 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002054 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002055intf_id %d, onu_id %d, uni_id %d, port_no %u, err = %s\n", tm_sched_key.id, intf_id, onu_id, uni_id, \
2056port_no, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002057 return err;
2058 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002059 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2060uni_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 -08002061
2062 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002063 bcmolt_itupon_alloc_cfg cfg;
2064 bcmolt_itupon_alloc_key key = { };
2065 key.pon_ni = intf_id;
2066 key.alloc_id = alloc_id;
2067 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
Burak Gurdag03919c72020-02-04 22:46:57 +00002068 int pir_bw = tf_sh_info.pir()*125; // conversion from kbps to bytes/sec
2069 int cir_bw = tf_sh_info.cir()*125; // conversion from kbps to bytes/sec
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002070 //offset to match bandwidth granularity
2071 int offset_pir_bw = pir_bw%bw_granularity;
2072 int offset_cir_bw = cir_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002073
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002074 pir_bw = pir_bw - offset_pir_bw;
2075 cir_bw = cir_bw - offset_cir_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002076
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002077 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002078
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002079 switch (additional_bw) {
2080 case 2: //AdditionalBW_BestEffort
2081 if (pir_bw == 0) {
2082 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2083%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002084 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002085 } else if (pir_bw < cir_bw) {
2086 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2087bandwidth (%d)\n", pir_bw, cir_bw);
2088 return BCM_ERR_PARM;
2089 } else if (pir_bw == cir_bw) {
2090 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2091bandwidth for additional bandwidth eligibility of type best_effort\n");
2092 return BCM_ERR_PARM;
2093 }
2094 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2095 break;
2096 case 1: //AdditionalBW_NA
2097 if (pir_bw == 0) {
2098 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2099%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2100 return BCM_ERR_PARM;
2101 } else if (cir_bw == 0) {
2102 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2103additional bandwidth eligibility of type Non-Assured (NA)\n");
2104 return BCM_ERR_PARM;
2105 } else if (pir_bw < cir_bw) {
2106 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2107bandwidth (%d)\n", pir_bw, cir_bw);
2108 return BCM_ERR_PARM;
2109 } else if (pir_bw == cir_bw) {
2110 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2111bandwidth for additional bandwidth eligibility of type non_assured\n");
2112 return BCM_ERR_PARM;
2113 }
2114 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2115 break;
2116 case 0: //AdditionalBW_None
2117 if (pir_bw == 0) {
2118 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
211916000 bytes/sec\n");
2120 return BCM_ERR_PARM;
2121 } else if (cir_bw == 0) {
2122 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2123for additional bandwidth eligibility of type None\n");
2124 return BCM_ERR_PARM;
2125 } else if (pir_bw > cir_bw) {
2126 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2127for additional bandwidth eligibility of type None\n");
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002128 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002129bandwidth in None eligibility\n", pir_bw);
2130 cir_bw = pir_bw;
2131 } else if (pir_bw < cir_bw) {
2132 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2133bandwidth (%d)\n", pir_bw, cir_bw);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002134 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002135bandwidth in None eligibility\n", pir_bw);
2136 cir_bw = pir_bw;
2137 }
2138 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2139 break;
2140 default:
2141 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002142 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002143 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2144 in a fine granularity. */
2145 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
2146 /* Fixed Bandwidth with no critical requirement of shaping */
2147 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, 0);
2148 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
2149 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, cir_bw);
2150 /* Maximum allocated bandwidth allowed for this alloc ID */
2151 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
2152 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002153 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002154 for skipped allocations during quiet window */
2155 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2156 /**< Allocation Profile index for CBR non-RT Bandwidth */
2157 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2158 /**< Allocation Profile index for CBR RT Bandwidth */
2159 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2160 /**< Alloc ID Weight used in case of Extended DBA mode */
2161 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2162 /**< Alloc ID Priority used in case of Extended DBA mode */
2163 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2164 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002165
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002166 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002167 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002168 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 -05002169port_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 -08002170 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002171 }
Girish Gowdra96461052019-11-22 20:13:59 +05302172
2173 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
2174 if (err) {
2175 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2176port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
2177 return err;
2178 }
2179
2180 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
2181port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
2182
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002183 }
2184
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002185 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002186}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002187
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002188Status CreateTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2189 uint32_t intf_id = traffic_scheds->intf_id();
2190 uint32_t onu_id = traffic_scheds->onu_id();
2191 uint32_t uni_id = traffic_scheds->uni_id();
2192 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002193 std::string direction;
2194 unsigned int alloc_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002195 tech_profile::SchedulerConfig sched_config;
2196 tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002197 uint32_t priority;
2198 uint32_t weight;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002199 tech_profile::SchedulingPolicy sched_policy;
2200 tech_profile::TrafficShapingInfo traffic_shaping_info;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002201 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002202 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002203
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002204 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2205 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002206
2207 direction = GetDirection(traffic_sched.direction());
2208 if (direction.compare("direction-not-supported") == 0)
2209 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2210
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002211 alloc_id = traffic_sched.alloc_id();
2212 sched_config = traffic_sched.scheduler();
2213 additional_bw = sched_config.additional_bw();
2214 priority = sched_config.priority();
2215 weight = sched_config.weight();
2216 sched_policy = sched_config.sched_policy();
2217 traffic_shaping_info = traffic_sched.traffic_shaping_info();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002218 tech_profile_id = traffic_sched.tech_profile_id();
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002219 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002220 sched_policy, traffic_shaping_info, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002221 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002222 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002223 return bcm_to_grpc_err(err, "Failed to create scheduler");
2224 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002225 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002226 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002227}
Jonathan Davis70c21812018-07-19 15:32:10 -04002228
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002229bcmos_errno RemoveSched(int intf_id, int onu_id, int uni_id, int alloc_id, std::string direction, int tech_profile_id) {
Jonathan Davis70c21812018-07-19 15:32:10 -04002230
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002231 bcmos_errno err;
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302232 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302233 bcmolt_status los_status;
Girish Gowdra96461052019-11-22 20:13:59 +05302234 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002235
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002236 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002237 bcmolt_itupon_alloc_cfg cfg;
2238 bcmolt_itupon_alloc_key key = { };
2239 key.pon_ni = intf_id;
2240 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302241 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002242
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002243 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002244 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2245 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002246 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2247 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002248 return err;
2249 }
Girish Gowdra96461052019-11-22 20:13:59 +05302250
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302251 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302252 if (err == BCM_ERR_OK) {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302253 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_OFF) {
2254 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 +05302255 intf_id);
2256 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2257 if (err) {
2258 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2259 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
2260 return err;
2261 }
2262 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302263 else if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_ON) {
2264 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is enabled but LoS status is ON, not waiting for alloc cfg clear response\n",
2265 intf_id);
2266 }
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302267 else if (state == BCMOLT_INTERFACE_STATE_INACTIVE) {
2268 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is disabled, not waiting for alloc cfg clear response\n",
2269 intf_id);
2270 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302271 } else {
2272 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 +05302273 intf_id, bcmos_strerror(err));
Girish Gowdra96461052019-11-22 20:13:59 +05302274 return err;
2275 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002276 } else if (direction == downstream) {
2277 bcmolt_tm_sched_cfg cfg;
2278 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002279
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002280 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2281 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302282 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002283 } else {
2284 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2285 return BCM_ERR_OK;
2286 }
Girish Gowdra96461052019-11-22 20:13:59 +05302287
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002288 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2289 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2290 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002291 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002292intf_id %d, onu_id %d, tech_profile_id %d, err = %s\n", direction.c_str(), key.id, intf_id, onu_id, tech_profile_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002293 return err;
2294 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002295 }
2296
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002297 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d, tech_profile_id %d\n",
2298 direction.c_str(), sched_id, intf_id, onu_id, tech_profile_id);
2299 free_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002300 return BCM_ERR_OK;
2301}
2302
2303Status RemoveTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2304 uint32_t intf_id = traffic_scheds->intf_id();
2305 uint32_t onu_id = traffic_scheds->onu_id();
2306 uint32_t uni_id = traffic_scheds->uni_id();
2307 std::string direction;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002308 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002309 bcmos_errno err;
2310
2311 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2312 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002313
2314 direction = GetDirection(traffic_sched.direction());
2315 if (direction.compare("direction-not-supported") == 0)
2316 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2317
2318 int alloc_id = traffic_sched.alloc_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002319 int tech_profile_id = traffic_sched.tech_profile_id();
2320 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002321 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002322 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002323 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2324 }
2325 }
2326 return Status::OK;
2327}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002328
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002329bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2330 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002331 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002332 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2333 bcmolt_tm_qmp_key tm_qmp_key;
2334 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002335
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002336 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2337 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002338 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed tm queue mapping profile count is 16.\n");
2339 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002340 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002341
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002342 tm_qmp_key.id = tm_qmp_id;
2343 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2344 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2345 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002346
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002347 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2348 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2349 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002350 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2351 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002352
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002353 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002354 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002355 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2356 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002357 return err;
2358 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002359
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002360 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2361 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002362 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002363}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002364
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002365bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2366 bcmos_errno err;
2367 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2368 bcmolt_tm_qmp_key tm_qmp_key;
2369 tm_qmp_key.id = tm_qmp_id;
2370
2371 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2372 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2373 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002374 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2375 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002376 return err;
2377 }
2378
2379 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2380 tm_qmp_key.id);
2381 return BCM_ERR_OK;
2382}
2383
2384bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2385 bcmos_errno err;
2386
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002387 /* Create default queues on the given PON/NNI scheduler */
2388 for (int queue_id = 0; queue_id < NUMBER_OF_DEFAULT_INTERFACE_QUEUES; queue_id++) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002389 bcmolt_tm_queue_cfg tm_queue_cfg;
2390 bcmolt_tm_queue_key tm_queue_key = {};
2391 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2392 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002393 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2394 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2395 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002396
2397 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2398 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2399 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2400
2401 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2402 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002403 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", \
2404 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 +00002405 return err;
2406 }
2407
2408 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2409 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2410 }
2411 return BCM_ERR_OK;
2412}
2413
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002414bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002415 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id, uint32_t tech_profile_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002416 bcmos_errno err;
2417 bcmolt_tm_queue_cfg cfg;
2418 bcmolt_tm_queue_key key = { };
2419 OPENOLT_LOG(INFO, openolt_log_id, "creating %s queue. access_intf_id = %d, onu_id = %d, uni_id = %d \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002420gemport_id = %d, tech_profile_id = %d\n", direction.c_str(), access_intf_id, onu_id, uni_id, gemport_id, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002421
2422 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002423 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002424
2425 if (priority > 7) {
2426 return BCM_ERR_RANGE;
2427 }
2428
2429 /* FIXME: The upstream queues have to be created once only.
2430 The upstream queues on the NNI scheduler are shared by all subscribers.
2431 When the first scheduler comes in, the queues get created, and are re-used by all others.
2432 Also, these queues should be present until the last subscriber exits the system.
2433 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2434
2435 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2436 for each GEM in TECH PROFILE */
2437 key.id = queue_id_list[priority];
2438
2439 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2440 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2441 key.id = 0;
2442 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2443 }
2444 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2445 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2446 }
2447 else {
2448 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2449 }
2450
2451 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2452
2453 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2454 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
2455
2456 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2457 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002458 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002459sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, tech_profile_id %d, err = %s\n", \
2460 direction.c_str(), key.id, key.sched_id, key.tm_q_set_id, access_intf_id, onu_id, uni_id, tech_profile_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002461 return err;
2462 }
2463
2464 OPENOLT_LOG(INFO, openolt_log_id, "Created tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002465intf_id %d, onu_id %d, uni_id %d, tech_profiled_id %d\n", direction.c_str(), key.id, key.sched_id, key.tm_q_set_id, access_intf_id, onu_id, uni_id, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002466 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002467}
2468
2469Status CreateTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2470 uint32_t intf_id = traffic_queues->intf_id();
2471 uint32_t onu_id = traffic_queues->onu_id();
2472 uint32_t uni_id = traffic_queues->uni_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002473 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002474 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002475 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002476 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002477 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 +00002478
2479 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2480 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2481 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2482 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2483 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
2484
2485 direction = GetDirection(traffic_queue.direction());
2486 if (direction.compare("direction-not-supported") == 0)
2487 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2488
2489 queues_priority_q[i] = traffic_queue.priority();
2490 queues_pbit_map[i] = traffic_queue.pbit_map();
2491 }
2492
2493 std::vector<uint32_t> tmq_map_profile(8, 0);
2494 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2495 queues_priority_q, COUNT_OF(queues_priority_q));
2496 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002497 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002498
2499 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2500 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002501 err = CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2502 if (err != BCM_ERR_OK) {
2503 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2504 return bcm_to_grpc_err(err, "Failed to create tm queue mapping profile");
2505 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002506 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2507 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2508 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2509 }
2510 }
2511
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002512 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2513 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002514
2515 direction = GetDirection(traffic_queue.direction());
2516 if (direction.compare("direction-not-supported") == 0)
2517 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2518
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002519 err = CreateQueue(direction, intf_id, onu_id, uni_id, qos_type, traffic_queue.priority(), traffic_queue.gemport_id(), tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002520
Girish Gowdruf26cf882019-05-01 23:47:58 -07002521 // If the queue exists already, lets not return failure and break the loop.
2522 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002523 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002524 return bcm_to_grpc_err(err, "Failed to create queue");
2525 }
2526 }
2527 return Status::OK;
2528}
2529
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002530bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002531 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id, uint32_t tech_profile_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002532 bcmolt_tm_queue_cfg cfg;
2533 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002534 bcmos_errno err;
2535
2536 if (direction == downstream) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002537 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2538 key.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002539 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002540 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002541 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 -08002542 return BCM_ERR_OK;
2543 }
2544 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002545 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2546 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002547 return BCM_ERR_OK;
2548 }
2549
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002550 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2551 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2552 // Reset the queue id to 0 when using fixed queue.
2553 key.id = 0;
2554 }
2555 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2556 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2557 }
2558 else {
2559 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2560 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002561
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002562 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2563 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002564 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002565 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, queue_id %d, sched_id %d, \
2566tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n",
2567 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 -08002568 return err;
2569 }
2570
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002571 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2572intf_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 -08002573
2574 return BCM_ERR_OK;
2575}
2576
2577Status RemoveTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2578 uint32_t intf_id = traffic_queues->intf_id();
2579 uint32_t onu_id = traffic_queues->onu_id();
2580 uint32_t uni_id = traffic_queues->uni_id();
2581 uint32_t port_no = traffic_queues->port_no();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002582 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002583 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002584 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002585 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002586 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 +00002587
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002588 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2589 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002590
2591 direction = GetDirection(traffic_queue.direction());
2592 if (direction.compare("direction-not-supported") == 0)
2593 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2594
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002595 err = RemoveQueue(direction, intf_id, onu_id, uni_id, qos_type, traffic_queue.priority(), traffic_queue.gemport_id(), tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002596 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002597 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002598 return bcm_to_grpc_err(err, "Failed to remove queue");
2599 }
Jonathan Davis70c21812018-07-19 15:32:10 -04002600 }
2601
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002602 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, tech_profile_id))) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002603 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002604 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002605
2606 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
2607 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002608 err = RemoveTrafficQueueMappingProfile(tm_qmp_id);
2609 if (err != BCM_ERR_OK) {
2610 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2611 return bcm_to_grpc_err(err, "Failed to remove tm queue mapping profile");
2612 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002613 }
2614 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002615 clear_qos_type(intf_id, onu_id, uni_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04002616 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04002617}
Jason Huangbf45ffb2019-10-30 17:29:02 +08002618
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002619Status PerformGroupOperation_(const openolt::Group *group_cfg) {
2620
2621 bcmos_errno err;
2622 bcmolt_group_key key = {};
2623 bcmolt_group_cfg grp_cfg_obj;
2624 bcmolt_group_members_update grp_mem_upd;
2625 bcmolt_members_update_command grp_mem_upd_cmd;
2626 bcmolt_group_member_info member_info = {};
2627 bcmolt_group_member_info_list_u8 members = {};
2628 bcmolt_intf_ref interface_ref = {};
2629 bcmolt_egress_qos egress_qos = {};
2630 bcmolt_tm_sched_ref tm_sched_ref = {};
2631 bcmolt_action a_val = {};
2632
2633 uint32_t group_id = group_cfg->group_id();
2634
2635 OPENOLT_LOG(INFO, openolt_log_id, "PerformGroupOperation request received for Group %d\n", group_id);
2636
2637 if (group_id >= 0) {
2638 key.id = group_id;
2639 }
2640 else {
2641 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
2642 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
2643 }
2644
2645 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2646 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
2647
2648 OPENOLT_LOG(INFO, openolt_log_id, "Checking if Group %d exists...\n",group_id);
2649
2650 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
2651 if (err != BCM_ERR_OK) {
2652 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
2653 return bcm_to_grpc_err(err, "Error in querying group");
2654 }
2655
2656 members.len = group_cfg->members_size();
2657
2658 // IMPORTANT: A member cannot be added to a group if the group type is not determined.
2659 // Group type is determined after a flow is assigned to it.
2660 // Therefore, a group must be created first, then a flow (with multicast type) must be assigned to it.
2661 // Only then we can add members to the group.
2662
2663 // if group does not exist, create it and return.
2664 if (grp_cfg_obj.data.state == BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
2665
2666 if (members.len != 0) {
2667 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);
2668 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Non-empty member list given for non-existent group");
2669 } else {
2670
2671 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2672 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, cookie, key.id);
2673
2674 /* Setting group actions and action parameters, if any.
2675 Only remove_outer_tag and translate_inner_tag actions and i_vid action parameter
2676 are supported for multicast groups in BAL 3.1.
2677 */
2678 const ::openolt::Action& action = group_cfg->action();
2679 const ::openolt::ActionCmd &cmd = action.cmd();
2680
2681 bcmolt_action_cmd_id cmd_bmask = BCMOLT_ACTION_CMD_ID_NONE;
2682 if (cmd.remove_outer_tag()) {
2683 OPENOLT_LOG(INFO, openolt_log_id, "Action remove_outer_tag applied to Group %d.\n", group_id);
2684 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
2685 }
2686
2687 if (cmd.translate_inner_tag()) {
2688 OPENOLT_LOG(INFO, openolt_log_id, "Action translate_inner_tag applied to Group %d.\n", group_id);
2689 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG);
2690 }
2691
2692 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, cmd_bmask);
2693
2694 if (action.i_vid()) {
2695 OPENOLT_LOG(INFO, openolt_log_id, "Setting action parameter i_vid=%d for Group %d.\n", action.i_vid(), group_id);
2696 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
2697 }
2698
2699 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, action, a_val);
2700
2701 // Create group
2702 err = bcmolt_cfg_set(dev_id, &(grp_cfg_obj.hdr));
2703
2704 if (BCM_ERR_OK != err) {
2705 BCM_LOG(ERROR, openolt_log_id, "Failed to create Group %d, err = %s (%d)\n", key.id, bcmos_strerror(err), err);
2706 return bcm_to_grpc_err(err, "Error in creating group");
2707 }
2708
2709 BCM_LOG(INFO, openolt_log_id, "Group %d has been created and configured with empty member list.\n", key.id);
2710 return Status::OK;
2711 }
2712 }
2713
2714 // The group already exists. Continue configuring it according to the update member command.
2715
2716 OPENOLT_LOG(INFO, openolt_log_id, "Configuring existing Group %d.\n",group_id);
2717
2718 // MEMBER LIST CONSTRUCTION
2719 // Note that members.len can be 0 here. if the group already exists and the command is SET then sending
2720 // empty list to the group is a legit operation and this actually empties the member list.
2721 members.arr = (bcmolt_group_member_info*)bcmos_calloc((members.len)*sizeof(bcmolt_group_member_info));
2722
2723 if (!members.arr) {
2724 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to allocate memory for group member list.\n");
2725 return grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "Memory exhausted during member list creation");
2726 }
2727
2728 /* SET GROUP MEMBERS UPDATE COMMAND */
2729 openolt::Group::GroupMembersCommand command = group_cfg->command();
2730 switch(command) {
2731 case openolt::Group::SET_MEMBERS :
2732 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_SET;
2733 OPENOLT_LOG(INFO, openolt_log_id, "Setting %d members for Group %d.\n", members.len, group_id);
2734 break;
2735 case openolt::Group::ADD_MEMBERS :
2736 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_ADD;
2737 OPENOLT_LOG(INFO, openolt_log_id, "Adding %d members to Group %d.\n", members.len, group_id);
2738 break;
2739 case openolt::Group::REMOVE_MEMBERS :
2740 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_REMOVE;
2741 OPENOLT_LOG(INFO, openolt_log_id, "Removing %d members from Group %d.\n", members.len, group_id);
2742 break;
2743 default :
2744 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid value %d for group member command.\n", command);
2745 bcmos_free(members.arr);
2746 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group member command");
2747 }
2748
2749 // SET MEMBERS LIST
2750 for (int i = 0; i < members.len; i++) {
2751
2752 if (command == openolt::Group::REMOVE_MEMBERS) {
2753 OPENOLT_LOG(INFO, openolt_log_id, "Removing group member %d from group %d\n",i,key.id);
2754 } else {
2755 OPENOLT_LOG(INFO, openolt_log_id, "Adding group member %d to group %d\n",i,key.id);
2756 }
2757
2758 openolt::GroupMember *member = (openolt::GroupMember *) &group_cfg->members()[i];
2759
2760 // Set member interface type
2761 openolt::GroupMember::InterfaceType if_type = member->interface_type();
2762 switch(if_type){
2763 case openolt::GroupMember::PON :
2764 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_PON);
2765 OPENOLT_LOG(INFO, openolt_log_id, "Interface type PON is assigned to GroupMember %d\n",i);
2766 break;
2767 case openolt::GroupMember::EPON_1G_PATH :
2768 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_1_G);
2769 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_1G is assigned to GroupMember %d\n",i);
2770 break;
2771 case openolt::GroupMember::EPON_10G_PATH :
2772 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_10_G);
2773 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_10G is assigned to GroupMember %d\n",i);
2774 break;
2775 default :
2776 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid interface type value %d for GroupMember %d.\n",if_type,i);
2777 bcmos_free(members.arr);
2778 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface type for a group member");
2779 }
2780
2781 // Set member interface id
2782 if (member->interface_id() >= 0) {
2783 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_id, member->interface_id());
2784 OPENOLT_LOG(INFO, openolt_log_id, "Interface %d is assigned to GroupMember %d\n", member->interface_id(), i);
2785 } else {
2786 bcmos_free(members.arr);
2787 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface id for a group member");
2788 }
2789
2790 // Set member interface_ref
2791 BCMOLT_FIELD_SET(&member_info, group_member_info, intf, interface_ref);
2792
2793 // Set member gem_port_id. This must be a multicast gemport.
2794 if (member->gem_port_id() >= 0) {
2795 BCMOLT_FIELD_SET(&member_info, group_member_info, svc_port_id, member->gem_port_id());
2796 OPENOLT_LOG(INFO, openolt_log_id, "GEM Port %d is assigned to GroupMember %d\n", member->gem_port_id(), i);
2797 } else {
2798 bcmos_free(members.arr);
2799 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid gem port id for a group member");
2800 }
2801
2802 // Set member scheduler id and queue_id
2803 uint32_t tm_sched_id = get_default_tm_sched_id(member->interface_id(), downstream);
2804 OPENOLT_LOG(INFO, openolt_log_id, "Scheduler %d is assigned to GroupMember %d\n", tm_sched_id, i);
2805 BCMOLT_FIELD_SET(&tm_sched_ref, tm_sched_ref, id, tm_sched_id);
2806 BCMOLT_FIELD_SET(&egress_qos, egress_qos, tm_sched, tm_sched_ref);
2807
2808 // We assume that all multicast traffic destined to a PON port is using the same fixed queue.
2809 uint32_t tm_queue_id;
2810 if (member->priority() >= 0 && member->priority() < NUMBER_OF_DEFAULT_INTERFACE_QUEUES) {
2811 tm_queue_id = queue_id_list[member->priority()];
2812 OPENOLT_LOG(INFO, openolt_log_id, "Queue %d is assigned to GroupMember %d\n", tm_queue_id, i);
2813 BCMOLT_FIELD_SET(&egress_qos, egress_qos, type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2814 BCMOLT_FIELD_SET(&egress_qos.u.fixed_queue, egress_qos_fixed_queue, queue_id, tm_queue_id);
2815 } else {
2816 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid fixed queue priority/ID %d for GroupMember %d\n", member->priority(), i);
2817 bcmos_free(members.arr);
2818 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid queue priority for a group member");
2819 }
2820
2821 BCMOLT_FIELD_SET(&member_info, group_member_info, egress_qos, egress_qos);
2822 BCMOLT_ARRAY_ELEM_SET(&(members), i, member_info);
2823 }
2824
2825 BCMOLT_OPER_INIT(&grp_mem_upd, group, members_update, key);
2826 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.members, members);
2827 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.command, grp_mem_upd_cmd);
2828
2829 err = bcmolt_oper_submit(dev_id, &(grp_mem_upd.hdr));
2830 bcmos_free(members.arr);
2831
2832 if (BCM_ERR_OK != err) {
2833 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);
2834 return bcm_to_grpc_err(err, "Failed to submit members update operation for the group");
2835 }
2836
2837 OPENOLT_LOG(INFO, openolt_log_id, "Successfully submitted members update operation for Group %d\n", key.id);
2838
2839 return Status::OK;
2840}
Burak Gurdageb4ca2e2020-06-15 07:48:26 +00002841
2842Status DeleteGroup_(uint32_t group_id) {
2843
2844 bcmos_errno err = BCM_ERR_OK;
2845 bcmolt_group_cfg grp_cfg_obj;
2846 bcmolt_group_key key = {};
2847
2848
2849 OPENOLT_LOG(INFO, openolt_log_id, "Delete request received for group %d\n", group_id);
2850
2851 if (group_id >= 0) {
2852 key.id = group_id;
2853 } else {
2854 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
2855 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
2856 }
2857
2858 /* init the BAL INIT API */
2859 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2860
2861 OPENOLT_LOG(DEBUG, openolt_log_id, "Checking if group %d exists...\n",group_id);
2862
2863 // CONFIGURE GROUP MEMBERS
2864 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
2865 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
2866
2867 if (err != BCM_ERR_OK) {
2868 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
2869 return bcm_to_grpc_err(err, "Error in querying group");
2870 }
2871
2872 if (grp_cfg_obj.data.state != BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
2873 OPENOLT_LOG(DEBUG, openolt_log_id, "Group %d exists. Will be deleted.\n",group_id);
2874 err = bcmolt_cfg_clear(dev_id, &(grp_cfg_obj.hdr));
2875 if (err != BCM_ERR_OK) {
2876 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d cannot be deleted err = %s (%d).\n", group_id, bcmos_strerror(err), err);
2877 return bcm_to_grpc_err(err, "Failed to delete group");;
2878 }
2879 } else {
2880 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d does not exist.\n", group_id);
2881 return Status(grpc::StatusCode::NOT_FOUND, "Group not found");
2882 }
2883
2884 OPENOLT_LOG(INFO, openolt_log_id, "Group %d has been deleted successfully.\n", group_id);
2885 return Status::OK;
Jason Huang1d9cfce2020-05-20 22:58:47 +08002886}
2887
2888Status GetLogicalOnuDistanceZero_(uint32_t intf_id, openolt::OnuLogicalDistance* response) {
2889 bcmos_errno err = BCM_ERR_OK;
2890 uint32_t mld = 0;
2891 double LD0;
2892
2893 err = getOnuMaxLogicalDistance(intf_id, &mld);
2894 if (err != BCM_ERR_OK) {
2895 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
2896 }
2897
2898 LD0 = LOGICAL_DISTANCE(mld*1000, MINIMUM_ONU_RESPONSE_RANGING_TIME, ONU_BIT_TRANSMISSION_DELAY);
2899 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance zero is %f, (PON %d)\n", LD0, intf_id);
2900 response->set_intf_id(intf_id);
2901 response->set_logical_onu_distance_zero(LD0);
2902
2903 return Status::OK;
2904}
2905
2906Status GetLogicalOnuDistance_(uint32_t intf_id, uint32_t onu_id, openolt::OnuLogicalDistance* response) {
2907 bcmos_errno err = BCM_ERR_OK;
2908 bcmolt_itu_onu_params itu = {};
2909 bcmolt_onu_cfg onu_cfg;
2910 bcmolt_onu_key onu_key = {};
2911 uint32_t mld = 0;
2912 double LDi;
2913
2914 onu_key.pon_ni = intf_id;
2915 onu_key.onu_id = onu_id;
2916
2917 err = getOnuMaxLogicalDistance(intf_id, &mld);
2918 if (err != BCM_ERR_OK) {
2919 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
2920 }
2921
2922 /* Initialize the API struct. */
2923 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
2924 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
2925 BCMOLT_FIELD_SET_PRESENT(&itu, itu_onu_params, ranging_time);
2926 BCMOLT_FIELD_SET(&onu_cfg.data, onu_cfg_data, itu, itu);
2927 #ifdef TEST_MODE
2928 // It is impossible to mock the setting of onu_cfg.data.onu_state because
2929 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
2930 // set the onu_cfg.data.onu_state. So a new stub function is created and address
2931 // of onu_cfg is passed. This is one-of case where we need to add test specific
2932 // code in production code.
2933 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
2934 #else
2935 /* Call API function. */
2936 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
2937 #endif
2938 if (err != BCM_ERR_OK) {
2939 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to retrieve ONU ranging time for PON %d/ONU id %d, err = %s (%d)\n", intf_id, onu_id, bcmos_strerror(err), err);
2940 return bcm_to_grpc_err(err, "Failed to retrieve ONU ranging time");
2941 }
2942
2943 if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_ACTIVE) {
2944 OPENOLT_LOG(ERROR, openolt_log_id, "ONU is not yet activated (PON %d, ONU id %d)\n", intf_id, onu_id);
2945 return bcm_to_grpc_err(BCM_ERR_PARM, "ONU is not yet activated\n");
2946 }
2947
2948 LDi = LOGICAL_DISTANCE(mld*1000, onu_cfg.data.itu.ranging_time, ONU_BIT_TRANSMISSION_DELAY);
2949 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance is %f, (PON %d, ONU id %d)\n", LDi, intf_id, onu_id);
2950 response->set_intf_id(intf_id);
2951 response->set_onu_id(onu_id);
2952 response->set_logical_onu_distance(LDi);
2953
2954 return Status::OK;
2955}