blob: aa45b0fba256e7cba9d28e5a4e08f92a60658a86 [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
kesavandc1f2db92020-08-31 15:32:06 +053093bcmolt_stat_alarm_config set_stat_alarm_config(const config::OnuItuPonAlarm* request) {
Jason Huang5d9ab1a2020-04-15 16:53:49 +080094 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()) {
kesavandc1f2db92020-08-31 15:32:06 +053099 case config::OnuItuPonAlarm::RATE_THRESHOLD:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800100 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;
kesavandc1f2db92020-08-31 15:32:06 +0530110 case config::OnuItuPonAlarm::RATE_RANGE:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800111 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;
kesavandc1f2db92020-08-31 15:32:06 +0530121 case config::OnuItuPonAlarm::VALUE_THRESHOLD:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800122 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
kesavandc1f2db92020-08-31 15:32:06 +0530142Status OnuItuPonAlarmSet_(const config::OnuItuPonAlarm* request) {
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800143 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()) {
kesavandc1f2db92020-08-31 15:32:06 +0530182 case config::OnuItuPonAlarm_AlarmID::OnuItuPonAlarm_AlarmID_RDI_ERRORS:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800183 //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
kesavandc1f2db92020-08-31 15:32:06 +0530914 //Enable AES Encryption
915 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.key_exchange, BCMOLT_CONTROL_STATE_ENABLE);
916 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.authentication, BCMOLT_CONTROL_STATE_ENABLE);
917 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.fail_due_to_authentication_failure, BCMOLT_CONTROL_STATE_ENABLE);
918
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000919 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
920 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
921
922 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
923 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500924 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 +0000925 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
926 }
927 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
928 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500929 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 +0000930 return bcm_to_grpc_err(err, "Failed to enable PON interface");
931 }
932 else {
933 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
934 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
935 CreateDefaultSched(intf_id, downstream);
936 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400937 }
938
939 return Status::OK;
940}
941
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500942Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000943 bcmos_errno err;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400944 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000945 bcmolt_device_key dev_key = { };
946 bcmolt_olt_cfg olt_cfg = { };
947 bcmolt_olt_key olt_key = { };
948 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
949 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500950
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000951 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
952 topo.topology_maps.arr = &topo_map[0];
953 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
954 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
955 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400956 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000957 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400958 #ifdef TEST_MODE
959 // It is impossible to mock the setting of olt_cfg.data.bal_state because
960 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
961 // set the olt_cfg.data.topology. So a new stub function is created and address
962 // of olt_cfg is passed. This is one-of case where we need to test add specific
963 // code in production code.
964 err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
965 #else
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000966 err = bcmolt_cfg_get_mult_retry(dev_id, &olt_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400967 #endif
968 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500969 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 +0000970 return bcm_to_grpc_err(err, "cfg: Failed to query OLT topology");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500971 }
972
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000973 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
974 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500975
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400976 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
977 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000978 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500979
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000980 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
981 num_of_nni_ports,
982 num_of_pon_ports,
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400983 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500984
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000985 uint32_t num_failed_cfg_gets = 0;
Jason Huang09b73ea2020-01-08 17:52:05 +0800986 static std::string openolt_version = firmware_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000987 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
988 dev_key.device_id = devid;
989 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
990 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
991 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
992 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000993 err = bcmolt_cfg_get_mult_retry(dev_id, &dev_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400994 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500995 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 +0000996 num_failed_cfg_gets++;
997 continue;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000998 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500999
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001000 std::string bal_version;
1001 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
1002 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
1003 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
Jason Huang09b73ea2020-01-08 17:52:05 +08001004 firmware_version = "BAL." + bal_version + "__" + openolt_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001005
1006 switch(dev_cfg.data.system_mode) {
1007 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
1008 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
1009 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
1010 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
1011 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
1012 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
1013 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
1014 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
1015 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
1016 case 20: board_technology = MIXED_TECH; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,MIXED_TECH); break;
1017 }
1018
1019 switch(dev_cfg.data.chip_family) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001020 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X: chip_family = "Maple"; break;
1021 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X: chip_family = "Aspen"; break;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001022 }
1023
Jason Huang09b73ea2020-01-08 17:52:05 +08001024 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s, family: %s, board_technology: %s\n",
1025 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 +00001026
1027 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001028 }
1029
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001030 /* 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 +00001031 only the devices that retured success*/
1032 if (num_failed_cfg_gets == BCM_MAX_DEVS_PER_LINE_CARD) {
1033 OPENOLT_LOG(ERROR, openolt_log_id, "device: Query of all the devices failed\n");
1034 return bcm_to_grpc_err(err, "device: All devices failed query");
1035 }
1036
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001037 return Status::OK;
1038}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001039
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001040Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001041 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001042 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
1043 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
1044 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001045
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001046 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001047 if (err == BCM_ERR_OK) {
1048 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001049 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001050 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1051 CreateDefaultSched(intf_id, upstream);
1052 CreateDefaultQueue(intf_id, upstream);
1053 return Status::OK;
1054 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1055 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
1056 return Status::OK;
1057 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001058 }
1059
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001060 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
1061 if (set_state) {
1062 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1063 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1064 } else {
1065 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1066 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1067 }
1068 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
1069 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001070 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err = %s\n",
1071 (set_state)?"enable":"disable", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001072 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
1073 }
1074 else {
1075 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
1076 if (set_state) {
1077 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1078 CreateDefaultSched(intf_id, upstream);
1079 CreateDefaultQueue(intf_id, upstream);
1080 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001081 }
1082
1083 return Status::OK;
1084}
1085
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001086Status DisablePonIf_(uint32_t intf_id) {
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001087 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001088 bcmolt_pon_interface_cfg interface_obj;
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001089 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1090 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001091
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001092 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
1093 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1094 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_DISABLE);
1095
1096 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1097 if (err != BCM_ERR_OK) {
1098 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable discovery of onu, PON interface %d, err %d\n", intf_id, err);
1099 return bcm_to_grpc_err(err, "Failed to disable discovery of onu");
1100 }
1101
1102 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1103 operation, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1104
1105 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1106 if (err != BCM_ERR_OK) {
1107 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 -04001108 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001109 }
1110
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001111 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled PON interface: %d\n", intf_id);
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001112 return Status::OK;
1113}
1114
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001115Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
kesavandc1f2db92020-08-31 15:32:06 +05301116 const char *vendor_id, const char *vendor_specific, uint32_t pir, bool omcc_encryption_mode) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001117 bcmos_errno err = BCM_ERR_OK;
1118 bcmolt_onu_cfg onu_cfg;
1119 bcmolt_onu_key onu_key;
1120 bcmolt_serial_number serial_number; /**< ONU serial number */
1121 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001122
Girish Gowdra24297032020-03-23 12:32:37 -07001123 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1124 bcmolt_onu_state onu_state;
1125
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001126 onu_key.onu_id = onu_id;
1127 onu_key.pon_ni = intf_id;
1128 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1129 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Girish Gowdra24297032020-03-23 12:32:37 -07001130#ifdef TEST_MODE
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001131 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1132 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1133 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1134 // of onu_cfg is passed. This is one-of case where we need to add test specific
1135 // code in production code.
1136 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Girish Gowdra24297032020-03-23 12:32:37 -07001137#else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001138 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Girish Gowdra24297032020-03-23 12:32:37 -07001139#endif
1140 OPENOLT_LOG(INFO, openolt_log_id, "Activate ONU : old state = %d, current state = %d\n",
1141 onu_cfg.data.onu_old_state, onu_cfg.data.onu_state);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001142 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001143 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) {
1144 OPENOLT_LOG(INFO, openolt_log_id, "ONU is already in ACTIVE state, \
1145not processing this request for pon_intf=%d onu_id=%d\n", intf_id, onu_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001146 return Status::OK;
Girish Gowdra24297032020-03-23 12:32:37 -07001147 } else if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_NOT_CONFIGURED &&
1148 onu_cfg.data.onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1149 // We need the ONU to be in NOT_CONFIGURED or INACTIVE state to further process the request
1150 OPENOLT_LOG(ERROR, openolt_log_id, "ONU in an invalid state to process the request, \
1151state=%d pon_intf=%d onu_id=%d\n", onu_cfg.data.onu_state, intf_id, onu_id);
1152 return bcm_to_grpc_err(err, "Failed to activate ONU, invalid ONU state");
1153 }
1154 } else {
1155 // This should never happen. BAL GET should succeed for non-existant ONUs too. The state of such ONUs will be NOT_CONFIGURED
1156 OPENOLT_LOG(ERROR, openolt_log_id, "ONU state query failed pon_intf=%d onu_id=%d\n", intf_id, onu_id);
1157 return bcm_to_grpc_err(err, "onu get failed");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001158 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001159
Girish Gowdra24297032020-03-23 12:32:37 -07001160 // If the ONU is not configured at all we need to first configure it
1161 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_NOT_CONFIGURED) {
1162 OPENOLT_LOG(INFO, openolt_log_id, "Configuring ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001163vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Girish Gowdra24297032020-03-23 12:32:37 -07001164 vendor_specific_to_str(vendor_specific).c_str(), pir);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001165
Girish Gowdra24297032020-03-23 12:32:37 -07001166 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1167 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1168 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1169 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1170 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1171 /*set burst and data profiles to fec disabled*/
1172 if (board_technology == "XGS-PON") {
1173 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1174 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1175 } else if (board_technology == "GPON") {
1176 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1177 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1178 }
1179 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1180 if (err != BCM_ERR_OK) {
1181 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to configure ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
1182 return bcm_to_grpc_err(err, "Failed to configure ONU");
1183 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001184 }
kesavandc1f2db92020-08-31 15:32:06 +05301185
1186 if (omcc_encryption_mode == true) {
1187 // set the encryption mode for omci port id
1188 bcmolt_itupon_gem_cfg gem_cfg;
1189 bcmolt_itupon_gem_key key = {};
1190 bcmolt_gem_port_configuration configuration = {};
1191 key.pon_ni = intf_id;
1192 key.gem_port_id = onu_id;
1193 bcmolt_control_state encryption_mode;
1194 encryption_mode = BCMOLT_CONTROL_STATE_ENABLE;
1195 BCMOLT_CFG_INIT(&gem_cfg, itupon_gem, key);
1196 BCMOLT_FIELD_SET(&gem_cfg.data, itupon_gem_cfg_data, encryption_mode, encryption_mode);
1197 err = bcmolt_cfg_set(dev_id, &gem_cfg.hdr);
1198 if(err != BCM_ERR_OK) {
1199 OPENOLT_LOG(ERROR, openolt_log_id, "failed to confiure omci gem_port encryption mode = %d\n", onu_id);
1200 return bcm_to_grpc_err(err, "Access_Control set ITU PON OMCI Gem port failed");
1201 }
1202 }
Girish Gowdra24297032020-03-23 12:32:37 -07001203 // Now that the ONU is configured, move the ONU to ACTIVE state
1204 memset(&onu_cfg, 0, sizeof(bcmolt_onu_cfg));
1205 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1206 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1207 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
1208 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
1209 onu_state, BCMOLT_ONU_OPERATION_ACTIVE);
1210 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001211 if (err != BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001212 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 +00001213 return bcm_to_grpc_err(err, "Failed to activate ONU");
1214 }
Girish Gowdra24297032020-03-23 12:32:37 -07001215 // ONU will eventually get activated after we have submitted the operation request. The adapter will receive an asynchronous
1216 // ONU_ACTIVATION_COMPLETED_INDICATION
1217
1218 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 +00001219
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001220 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001221}
1222
Jonathan Davis70c21812018-07-19 15:32:10 -04001223Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1224 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001225 bcmos_errno err = BCM_ERR_OK;
1226 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1227 bcmolt_onu_cfg onu_cfg;
1228 bcmolt_onu_key onu_key; /**< Object key. */
1229 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001230
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001231 onu_key.onu_id = onu_id;
1232 onu_key.pon_ni = intf_id;
1233 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1234 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001235 #ifdef TEST_MODE
1236 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1237 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1238 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1239 // of onu_cfg is passed. This is one-of case where we need to add test specific
1240 // code in production code.
1241 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001242 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001243 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001244 #endif
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301245 onu_state = onu_cfg.data.onu_state;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001246 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001247 switch (onu_state) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001248 case BCMOLT_ONU_STATE_ACTIVE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001249 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001250 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001251 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1252 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1253 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001254 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 +00001255 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1256 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301257 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 +00001258 break;
1259 }
Jonathan Davis70c21812018-07-19 15:32:10 -04001260 }
1261
1262 return Status::OK;
1263}
1264
1265Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001266 const char *vendor_id, const char *vendor_specific) {
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301267 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301268 bcmolt_onu_state onu_state;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001269
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001270 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 -05001271 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1272
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001273 // Need to deactivate before removing it (BAL rules)
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001274 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301275
1276 err = get_onu_status((bcmolt_interface)intf_id, onu_id, &onu_state);
1277 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001278 if (onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1279 OPENOLT_LOG(INFO, openolt_log_id, "waiting for onu deactivate complete response: intf_id=%d, onu_id=%d\n",
1280 intf_id, onu_id);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301281 err = wait_for_onu_deactivate_complete(intf_id, onu_id);
1282 if (err) {
1283 OPENOLT_LOG(ERROR, openolt_log_id, "failed to delete onu intf_id %d, onu_id %d\n",
1284 intf_id, onu_id);
1285 return bcm_to_grpc_err(err, "Failed to delete ONU");
1286 }
1287 }
Girish Gowdra24297032020-03-23 12:32:37 -07001288 else {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301289 OPENOLT_LOG(INFO, openolt_log_id, "Onu is Inactive, onu_id: %d, not waiting for onu deactivate complete response\n",
1290 intf_id);
1291 }
1292 }
1293 else {
1294 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch Onu status, onu_id = %d, intf_id = %d, err = %s\n",
1295 onu_id, intf_id, bcmos_strerror(err));
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301296 return bcm_to_grpc_err(err, "Failed to delete ONU");
1297 }
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001298
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001299 bcmolt_onu_cfg cfg_obj;
1300 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001301
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001302 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 -04001303 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001304
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001305 key.onu_id = onu_id;
1306 key.pon_ni = intf_id;
1307 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001308
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301309 err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001310 if (err != BCM_ERR_OK)
1311 {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001312 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 -04001313 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1314 }
1315
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301316 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 +00001317 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001318}
1319
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001320#define MAX_CHAR_LENGTH 20
1321#define MAX_OMCI_MSG_LENGTH 44
1322Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001323 bcmolt_bin_str buf = {};
1324 bcmolt_onu_cpu_packets omci_cpu_packets;
1325 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001326
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001327 key.pon_ni = intf_id;
1328 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001329
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001330 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1331 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1332 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001333
1334 // ???
1335 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1336 buf.len = MAX_OMCI_MSG_LENGTH;
1337 } else {
1338 buf.len = pkt.size()/2;
1339 }
1340
1341 /* Send the OMCI packet using the BAL remote proxy API */
1342 uint16_t idx1 = 0;
1343 uint16_t idx2 = 0;
1344 uint8_t arraySend[buf.len];
1345 char str1[MAX_CHAR_LENGTH];
1346 char str2[MAX_CHAR_LENGTH];
1347 memset(&arraySend, 0, buf.len);
1348
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001349 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1350 sprintf(str1,"%c", pkt[idx1]);
1351 sprintf(str2,"%c", pkt[++idx1]);
1352 strcat(str1,str2);
1353 arraySend[idx2] = strtol(str1, NULL, 16);
1354 }
1355
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001356 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1357 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001358
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001359 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1360 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1361 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001362
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001363 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001364 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001365 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 +00001366 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001367 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001368 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 -05001369 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001370 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001371 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001372
1373 return Status::OK;
1374}
1375
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001376Status 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 +00001377 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1378 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1379 bcmolt_bin_str buf = {};
1380 bcmolt_gem_port_id gem_port_id_array[1];
1381 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001382
Craig Lutgen967a1d02018-11-27 10:41:51 -06001383 if (port_no > 0) {
1384 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001385 if (gemport_id == 0) {
1386 bcmos_fastlock_lock(&data_lock);
1387 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1388 // Pick any flow that is mapped with the same port_no.
1389 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1390 if (it != port_to_flows.end() && !it->second.empty()) {
1391 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1392 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1393 if (fit != flowid_to_gemport.end()) {
1394 found = true;
1395 gemport_id = fit->second;
1396 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001397 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001398 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001399
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001400 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001401 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 -08001402 onu_id, port_no, intf_id);
1403 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1404 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001405 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 -08001406 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001407 }
1408
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001409 gem_port_id_array[0] = gemport_id;
1410 gem_port_list.len = 1;
1411 gem_port_list.arr = gem_port_id_array;
1412 buf.len = pkt.size();
1413 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1414 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1415
1416 /* init the API struct */
1417 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1418 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1419 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1420 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1421 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1422
1423 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1424 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1425
1426 /* call API */
1427 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001428 }
1429 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001430 //TODO: Port No is 0, it is coming sender requirement.
1431 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1432 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001433 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001434 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001435
1436 return Status::OK;
1437}
1438
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001439Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001440 bcmolt_flow_key key = {}; /* declare key */
1441 bcmolt_bin_str buffer = {};
1442 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001443
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001444 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
1445 bcmolt_flow_id flow_id = 0;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001446
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001447 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1448 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1449 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1450 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1451 key.flow_id = flow_id;
1452 else {
Jason Huang09b73ea2020-01-08 17:52:05 +08001453 if (flow_id_counters) {
1454 std::map<flow_pair, int>::iterator it;
1455 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1456 int flow_index = it->first.first;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001457 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1458 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1459 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1460 key.flow_id = flow_index;
1461 break;
1462 }
1463 }
1464 }
1465 else {
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001466 OPENOLT_LOG(ERROR, openolt_log_id, "no flow id found for uplink packetout\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001467 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1468 }
1469 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001470
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001471 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001472
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001473 /* Initialize the API struct. */
1474 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001475
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001476 buffer.len = pkt.size();
1477 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1478 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1479 if (buffer.arr == NULL) {
1480 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1481 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1482 }
1483 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1484
1485 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1486 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001487 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 -05001488 return bcm_to_grpc_err(BCM_ERR_SYSCALL_ERR, "Error sending packets via nni port");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001489 } else {
1490 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1491 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001492
1493 return Status::OK;
1494}
Craig Lutgen967a1d02018-11-27 10:41:51 -06001495Status 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 +00001496 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001497 int32_t alloc_id, int32_t network_intf_id,
1498 int32_t gemport_id, const ::openolt::Classifier& classifier,
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001499 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00001500 int32_t group_id, uint32_t tech_profile_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001501 bcmolt_flow_cfg cfg;
1502 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001503 int32_t o_vid = -1;
1504 bool single_tag = false;
1505 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001506 bcmolt_classifier c_val = { };
1507 bcmolt_action a_val = { };
1508 bcmolt_tm_queue_ref tm_val = { };
1509 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05001510 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001511
Jason Huang09b73ea2020-01-08 17:52:05 +08001512 OPENOLT_LOG(INFO, openolt_log_id, "flow add received for flow_id=%u, flow_type=%s\n", flow_id, flow_type.c_str());
1513
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001514 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001515 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001516 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001517 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001518 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001519 } else if (flow_type.compare(multicast) == 0) {
1520 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001521 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001522 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001523 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001524 }
1525
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001526 BCMOLT_CFG_INIT(&cfg, flow, key);
1527 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001528
Jason Huang09b73ea2020-01-08 17:52:05 +08001529 if (action.cmd().trap_to_host()) {
1530 Status resp = handle_acl_rule_install(onu_id, flow_id, flow_type, access_intf_id,
1531 network_intf_id, gemport_id, classifier);
1532 return resp;
1533 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001534
1535 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1536
1537 if (access_intf_id >= 0 && network_intf_id >= 0) {
1538 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1539 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1540 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08001541 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1542 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001543 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1544 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1545 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1546 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1547 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001548 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001549 } else {
1550 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
1551 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001552 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001553
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001554 if (onu_id >= 0) {
1555 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
1556 }
1557 if (gemport_id >= 0) {
1558 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
1559 }
1560 if (gemport_id >= 0 && port_no != 0) {
1561 bcmos_fastlock_lock(&data_lock);
1562 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
1563 port_to_flows[port_no].insert(key.flow_id);
1564 flowid_to_gemport[key.flow_id] = gemport_id;
1565 }
1566 else
1567 {
1568 flowid_to_port[key.flow_id] = port_no;
1569 }
1570 bcmos_fastlock_unlock(&data_lock, 0);
1571 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001572 if (gemport_id >= 0 && access_intf_id >= 0) {
1573 // Update the flow_to_acl_map. Note that since this is a datapath flow, acl_id is -1
1574 // This info is needed during flow remove where we need to retrieve the gemport_id
1575 // and access_intf id for the given flow id and flow direction.
1576 // After retrieving the ACL ID and GEM PORT ID, we decrement the corresponding
1577 // reference counters for those ACL ID and GEMPORT ID.
1578 acl_id_gem_id_intf_id ac_id_gm_id_if_id(-1, gemport_id, access_intf_id);
1579 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
1580 bcmos_fastlock_lock(&data_lock);
1581 flow_to_acl_map[fl_id_fl_dir] = ac_id_gm_id_if_id;
1582 bcmos_fastlock_unlock(&data_lock, 0);
1583 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001584 if (priority_value >= 0) {
1585 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
1586 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301587
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001588 } else { // MULTICAST FLOW
1589 if (group_id >= 0) {
1590 BCMOLT_MSG_FIELD_SET(&cfg, group_id, group_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001591 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001592 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1593 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001594 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001595
1596 {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001597 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001598 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001599 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
1600 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001601 }
1602
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001603 if (classifier.dst_mac().size() > 0) {
1604 bcmos_mac_address d_mac = {};
1605 bcmos_mac_address_init(&d_mac);
1606 memcpy(d_mac.u8, classifier.dst_mac().data(), sizeof(d_mac.u8));
1607 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_mac %02x:%02x:%02x:%02x:%02x:%02x\n", d_mac.u8[0],
1608 d_mac.u8[1], d_mac.u8[2], d_mac.u8[3], d_mac.u8[4], d_mac.u8[5]);
1609 BCMOLT_FIELD_SET(&c_val, classifier, dst_mac, d_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001610 }
1611
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001612 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001613 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001614 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001615 }
1616 */
1617
1618 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001619 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
1620 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001621 }
1622
1623 /*
1624 if (classifier.dst_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001625 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_ip, classifier.dst_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001626 }
1627
1628 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001629 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001630 }
1631 */
1632
1633 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001634 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
1635 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001636 }
1637
1638 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001639 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
1640 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001641 }
1642
1643 if (!classifier.pkt_tag_type().empty()) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001644 if (classifier.o_vid()) {
1645 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
1646 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
1647 }
1648
1649 if (classifier.i_vid()) {
1650 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
1651 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
1652 }
1653
1654 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
1655 if (classifier.pkt_tag_type().compare("untagged") == 0) {
1656 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
1657 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
1658 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
1659 single_tag = true;
1660
1661 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301662 // OpenOlt adapter will send 0xFF in case of no pbit classification
1663 // If it is any other value (0 to 7), it is for outer pbit classification.
1664 // OpenFlow protocol does not provide inner pbit classification (in case of double tagged packets),
1665 // and VOLTHA has not used any workaround to solve this problem (for ex: use metadata field).
1666 // Also there exists no use case for i-pbit classification, so we can safely ignore this for now.
1667 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001668 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301669 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001670 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
1671 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001672
Jason Huang09b73ea2020-01-08 17:52:05 +08001673 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301674 // Same comments as in case of "single_tag" packets.
1675 // 0xFF means no pbit classification, otherwise a valid PCP (0 to 7).
1676 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001677 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301678 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001679 }
1680 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001681 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001682 }
1683
Jason Huang09b73ea2020-01-08 17:52:05 +08001684 const ::openolt::ActionCmd& cmd = action.cmd();
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001685
Jason Huang09b73ea2020-01-08 17:52:05 +08001686 if (cmd.add_outer_tag()) {
1687 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
1688 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001689 }
1690
Jason Huang09b73ea2020-01-08 17:52:05 +08001691 if (cmd.remove_outer_tag()) {
1692 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
1693 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
1694 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301695
Jason Huang09b73ea2020-01-08 17:52:05 +08001696 if (action.o_vid()) {
1697 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
1698 o_vid = action.o_vid();
1699 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
1700 }
1701
1702 if (action.o_pbits()) {
1703 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
1704 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
1705 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301706
Jason Huang09b73ea2020-01-08 17:52:05 +08001707 if (action.i_vid()) {
1708 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
1709 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
1710 }
1711
1712 if (action.i_pbits()) {
1713 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
1714 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
1715 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301716
Jason Huang09b73ea2020-01-08 17:52:05 +08001717 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
1718
Shad Ansari39739bc2018-09-13 21:38:37 +00001719 if ((access_intf_id >= 0) && (onu_id >= 0)) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001720 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
1721 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00001722 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 +00001723
Jason Huang09b73ea2020-01-08 17:52:05 +08001724 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1725 // Queue 0 on DS subscriber scheduler
1726 tm_val.queue_id = 0;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001727
Jason Huang09b73ea2020-01-08 17:52:05 +08001728 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1729 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1730 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001731
Jason Huang09b73ea2020-01-08 17:52:05 +08001732 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1733 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1734 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001735
Jason Huang09b73ea2020-01-08 17:52:05 +08001736 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1737 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
1738 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 +00001739
Jason Huang09b73ea2020-01-08 17:52:05 +08001740 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1741 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1742 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1743 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 +00001744
Jason Huang09b73ea2020-01-08 17:52:05 +08001745 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
1746 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1747 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1748 }
1749 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
1750 // NNI Scheduler ID
1751 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1752 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1753 // Queue 0 on NNI scheduler
1754 tm_val.queue_id = 0;
1755 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1756 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1757 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001758
Jason Huang09b73ea2020-01-08 17:52:05 +08001759 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 +00001760 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1761 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1762
Jason Huang09b73ea2020-01-08 17:52:05 +08001763 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1764 /* Fetch TM QMP ID mapped to US NNI scheduler */
1765 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
1766 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1767 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1768 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1769 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 +00001770
Jason Huang09b73ea2020-01-08 17:52:05 +08001771 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 +00001772 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1773 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001774 }
Shad Ansari39739bc2018-09-13 21:38:37 +00001775 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301776 } else {
1777 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1778 tm_val.queue_id = 0;
1779
1780 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
1781 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1782 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
1783
1784 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1785 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
1786 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00001787 }
1788
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001789 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001790
1791 // BAL 3.1 supports statistics only for unicast flows.
1792 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1793 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
1794 }
1795
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001796#ifdef FLOW_CHECKER
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001797 //Flow Checker, To avoid duplicate flow.
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001798 if (flow_id_counters != 0) {
1799 bool b_duplicate_flow = false;
Jason Huang09b73ea2020-01-08 17:52:05 +08001800 std::map<flow_pair, int>::iterator it;
1801
1802 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1803 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(it->first.first, it->first.second, ONU_ID)) && \
1804 (key.flow_type == it->first.second) && \
1805 (cfg.data.svc_port_id == get_flow_status(it->first.first, it->first.second, SVC_PORT_ID)) && \
1806 (cfg.data.priority == get_flow_status(it->first.first, it->first.second, PRIORITY)) && \
1807 (cfg.data.cookie == get_flow_status(it->first.first, it->first.second, COOKIE)) && \
1808 (cfg.data.ingress_intf.intf_type == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_TYPE)) && \
1809 (cfg.data.ingress_intf.intf_id == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_ID)) && \
1810 (cfg.data.egress_intf.intf_type == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_TYPE)) && \
1811 (cfg.data.egress_intf.intf_id == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_ID)) && \
1812 (c_val.o_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_VID)) && \
1813 (c_val.o_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_PBITS)) && \
1814 (c_val.i_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_VID)) && \
1815 (c_val.i_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_PBITS)) && \
1816 (c_val.ether_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_ETHER_TYPE)) && \
1817 (c_val.ip_proto == get_flow_status(it->first.first, it->first.second, CLASSIFIER_IP_PROTO)) && \
1818 (c_val.src_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_SRC_PORT)) && \
1819 (c_val.dst_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_DST_PORT)) && \
1820 (c_val.pkt_tag_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_PKT_TAG_TYPE)) && \
1821 (cfg.data.egress_qos.type == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TYPE)) && \
1822 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_QUEUE_ID)) && \
1823 (cfg.data.egress_qos.tm_sched.id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TM_SCHED_ID)) && \
1824 (a_val.cmds_bitmask == get_flow_status(it->first.first, it->first.second, ACTION_CMDS_BITMASK)) && \
1825 (a_val.o_vid == get_flow_status(it->first.first, it->first.second, ACTION_O_VID)) && \
1826 (a_val.i_vid == get_flow_status(it->first.first, it->first.second, ACTION_I_VID)) && \
1827 (a_val.o_pbits == get_flow_status(it->first.first, it->first.second, ACTION_O_PBITS)) && \
1828 (a_val.i_pbits == get_flow_status(it->first.first, it->first.second, ACTION_I_PBITS)) && \
1829 (cfg.data.state == get_flow_status(it->first.first, it->first.second, STATE)) && \
1830 (cfg.data.group_id == get_flow_status(it->first.first, it->first.second, GROUP_ID));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001831#ifdef SHOW_FLOW_PARAM
1832 // Flow Parameter
1833 FLOW_PARAM_LOG();
1834#endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001835 if (b_duplicate_flow) {
1836 FLOW_LOG(WARNING, "Flow duplicate", 0);
1837 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
1838 }
1839 }
1840 }
1841#endif
1842
1843 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
1844 if (err) {
1845 FLOW_LOG(ERROR, "Flow add failed", err);
1846 return bcm_to_grpc_err(err, "flow add failed");
1847 } else {
1848 FLOW_LOG(INFO, "Flow add ok", err);
1849 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08001850 flow_map[std::pair<int, int>(key.flow_id,key.flow_type)] = flow_map.size();
1851 flow_id_counters = flow_map.size();
1852 if (gemport_id > 0 && access_intf_id >= 0) {
1853 gem_id_intf_id gem_intf(gemport_id, access_intf_id);
1854 if (gem_ref_cnt.count(gem_intf) > 0) {
1855 // The gem port is already installed
1856 // Increment the ref counter indicating number of flows referencing this gem port
1857 gem_ref_cnt[gem_intf]++;
1858 OPENOLT_LOG(DEBUG, openolt_log_id, "incremented gem_ref_cnt, gem_ref_cnt=%d\n", gem_ref_cnt[gem_intf]);
1859 } else {
1860 // Initialize the refence count for the gemport.
1861 gem_ref_cnt[gem_intf] = 1;
1862 OPENOLT_LOG(DEBUG, openolt_log_id, "initialized gem_ref_cnt\n");
1863 }
1864 } else {
1865 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);
1866 }
1867
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001868 bcmos_fastlock_unlock(&data_lock, 0);
1869 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04001870
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001871 return Status::OK;
1872}
1873
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001874Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
1875
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001876 bcmolt_flow_cfg cfg;
1877 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001878
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001879 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001880 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001881 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001882 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001883 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001884 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001885 } else if(flow_type.compare(multicast) == 0) {
1886 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001887 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001888 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001889 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
1890 }
1891
Jason Huang09b73ea2020-01-08 17:52:05 +08001892 OPENOLT_LOG(INFO, openolt_log_id, "flow remove received for flow_id=%u, flow_type=%s\n",
1893 flow_id, flow_type.c_str());
1894
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001895 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08001896 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
1897 int32_t gemport_id = -1;
1898 int32_t intf_id = -1;
1899 int16_t acl_id = -1;
1900 if (flow_to_acl_map.count(fl_id_fl_dir) > 0) {
1901 acl_id_gem_id_intf_id ac_id_gm_id_if_id = flow_to_acl_map[fl_id_fl_dir];
1902 acl_id = std::get<0>(ac_id_gm_id_if_id);
1903 gemport_id = std::get<1>(ac_id_gm_id_if_id);
1904 intf_id = std::get<2>(ac_id_gm_id_if_id);
1905 // cleanup acl only if it is a valid acl. If not valid acl, it may be datapath flow.
1906 if (acl_id >= 0) {
1907 Status resp = handle_acl_rule_cleanup(acl_id, gemport_id, intf_id, flow_type);
1908 bcmos_fastlock_unlock(&data_lock, 0);
1909 if (resp.ok()) {
1910 OPENOLT_LOG(INFO, openolt_log_id, "acl removed ok for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
1911 flow_to_acl_map.erase(fl_id_fl_dir);
1912 } else {
1913 OPENOLT_LOG(ERROR, openolt_log_id, "acl remove error for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
1914 }
1915 return resp;
1916 }
1917 }
1918
Craig Lutgen967a1d02018-11-27 10:41:51 -06001919 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001920 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06001921 flowid_to_gemport.erase(key.flow_id);
1922 port_to_flows[port_no].erase(key.flow_id);
1923 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
1924 }
1925 else
1926 {
1927 flowid_to_port.erase(key.flow_id);
1928 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001929 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001930
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001931 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001932
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001933 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001934 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001935 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 -04001936 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
1937 }
1938
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001939 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08001940 if (flow_id_counters != 0) {
1941 std::map<flow_pair, int>::iterator it;
1942 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1943 if (it->first.first == flow_id && it->first.second == key.flow_type) {
1944 flow_id_counters -= 1;
1945 flow_map.erase(it);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001946 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001947 }
1948 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001949 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
1950
1951 clear_gem_port(gemport_id, intf_id);
1952
1953 flow_to_acl_map.erase(fl_id_fl_dir);
1954
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001955 bcmos_fastlock_unlock(&data_lock, 0);
1956
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001957 return Status::OK;
1958}
1959
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001960bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
1961 bcmos_errno err;
1962 bcmolt_tm_sched_cfg tm_sched_cfg;
1963 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
1964 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
1965
Jason Huangbf45ffb2019-10-30 17:29:02 +08001966 //check TM scheduler has configured or not
1967 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
1968 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001969 #ifdef TEST_MODE
1970 // It is impossible to mock the setting of tm_sched_cfg.data.state because
1971 // the actual bcmolt_cfg_get passes the address of tm_sched_cfg.hdr and we cannot
1972 // set the tm_sched_cfg.data.state. So a new stub function is created and address
1973 // of tm_sched_cfg is passed. This is one-of case where we need to add test specific
1974 // code in production code.
1975 err = bcmolt_cfg_get__tm_sched_stub(dev_id, &tm_sched_cfg);
1976 #else
Jason Huangbf45ffb2019-10-30 17:29:02 +08001977 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001978 #endif
Jason Huangbf45ffb2019-10-30 17:29:02 +08001979 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001980 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 +08001981 return err;
1982 }
1983 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
1984 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
1985 return BCM_ERR_OK;
1986 }
1987
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001988 // bcmbal_tm_sched_owner
1989 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
1990
1991 /**< The output of the tm_sched object instance */
1992 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
1993
1994 if (direction.compare(upstream) == 0) {
1995 // In upstream it is NNI scheduler
1996 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
1997 } else if (direction.compare(downstream) == 0) {
1998 // In downstream it is PON scheduler
1999 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2000 }
2001
2002 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2003
2004 // bcmbal_tm_sched_type
2005 // set the deafult policy to strict priority
2006 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2007
2008 // num_priorities: Max number of strict priority scheduling elements
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002009 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, NUM_OF_PRIORITIES);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002010
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002011 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2012 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002013 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
2014 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002015 return err;
2016 }
2017
2018 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2019 direction.c_str(), tm_sched_key.id, intf_id);
2020 return BCM_ERR_OK;
2021}
2022
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002023bcmos_errno CreateSched(std::string direction, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t port_no,
2024 uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002025 tech_profile::SchedulingPolicy sched_policy, tech_profile::TrafficShapingInfo tf_sh_info,
2026 uint32_t tech_profile_id) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002027
2028 bcmos_errno err;
2029
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002030 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002031 bcmolt_tm_sched_cfg tm_sched_cfg;
2032 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002033 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 -04002034
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002035 // bcmbal_tm_sched_owner
2036 // In downstream it is sub_term scheduler
2037 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002038
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002039 /**< The output of the tm_sched object instance */
2040 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002041
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002042 // bcmbal_tm_sched_parent
2043 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2044 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
2045 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 +00002046 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002047 be achieved using the' virtual' type of attachment.
2048 tm_sched_owner.u.sub_term.intf_id = intf_id;
2049 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2050 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002051
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002052 // bcmbal_tm_sched_type
2053 // set the deafult policy to strict priority
2054 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002055
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002056 // num_priorities: Max number of strict priority scheduling elements
2057 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002058
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002059 // bcmbal_tm_shaping
2060 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2061 uint32_t cir = tf_sh_info.cir();
2062 uint32_t pir = tf_sh_info.pir();
2063 uint32_t burst = tf_sh_info.pbs();
2064 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2065 cir, pir, burst);
2066 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2067 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2068 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2069 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2070 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2071 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002072 }
2073
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002074 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002075 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002076 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002077intf_id %d, onu_id %d, uni_id %d, port_no %u, err = %s\n", tm_sched_key.id, intf_id, onu_id, uni_id, \
2078port_no, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002079 return err;
2080 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002081 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2082uni_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 -08002083
2084 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002085 bcmolt_itupon_alloc_cfg cfg;
2086 bcmolt_itupon_alloc_key key = { };
2087 key.pon_ni = intf_id;
2088 key.alloc_id = alloc_id;
2089 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
Burak Gurdag03919c72020-02-04 22:46:57 +00002090 int pir_bw = tf_sh_info.pir()*125; // conversion from kbps to bytes/sec
2091 int cir_bw = tf_sh_info.cir()*125; // conversion from kbps to bytes/sec
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002092 //offset to match bandwidth granularity
2093 int offset_pir_bw = pir_bw%bw_granularity;
2094 int offset_cir_bw = cir_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002095
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002096 pir_bw = pir_bw - offset_pir_bw;
2097 cir_bw = cir_bw - offset_cir_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002098
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002099 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002100
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002101 switch (additional_bw) {
2102 case 2: //AdditionalBW_BestEffort
2103 if (pir_bw == 0) {
2104 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2105%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002106 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002107 } else if (pir_bw < cir_bw) {
2108 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2109bandwidth (%d)\n", pir_bw, cir_bw);
2110 return BCM_ERR_PARM;
2111 } else if (pir_bw == cir_bw) {
2112 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2113bandwidth for additional bandwidth eligibility of type best_effort\n");
2114 return BCM_ERR_PARM;
2115 }
2116 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2117 break;
2118 case 1: //AdditionalBW_NA
2119 if (pir_bw == 0) {
2120 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2121%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2122 return BCM_ERR_PARM;
2123 } else if (cir_bw == 0) {
2124 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2125additional bandwidth eligibility of type Non-Assured (NA)\n");
2126 return BCM_ERR_PARM;
2127 } else if (pir_bw < cir_bw) {
2128 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2129bandwidth (%d)\n", pir_bw, cir_bw);
2130 return BCM_ERR_PARM;
2131 } else if (pir_bw == cir_bw) {
2132 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2133bandwidth for additional bandwidth eligibility of type non_assured\n");
2134 return BCM_ERR_PARM;
2135 }
2136 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2137 break;
2138 case 0: //AdditionalBW_None
2139 if (pir_bw == 0) {
2140 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
214116000 bytes/sec\n");
2142 return BCM_ERR_PARM;
2143 } else if (cir_bw == 0) {
2144 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2145for additional bandwidth eligibility of type None\n");
2146 return BCM_ERR_PARM;
2147 } else if (pir_bw > cir_bw) {
2148 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2149for additional bandwidth eligibility of type None\n");
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002150 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002151bandwidth in None eligibility\n", pir_bw);
2152 cir_bw = pir_bw;
2153 } else if (pir_bw < cir_bw) {
2154 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2155bandwidth (%d)\n", pir_bw, cir_bw);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002156 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002157bandwidth in None eligibility\n", pir_bw);
2158 cir_bw = pir_bw;
2159 }
2160 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2161 break;
2162 default:
2163 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002164 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002165 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2166 in a fine granularity. */
2167 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
2168 /* Fixed Bandwidth with no critical requirement of shaping */
2169 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, 0);
2170 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
2171 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, cir_bw);
2172 /* Maximum allocated bandwidth allowed for this alloc ID */
2173 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
2174 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002175 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002176 for skipped allocations during quiet window */
2177 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2178 /**< Allocation Profile index for CBR non-RT Bandwidth */
2179 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2180 /**< Allocation Profile index for CBR RT Bandwidth */
2181 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2182 /**< Alloc ID Weight used in case of Extended DBA mode */
2183 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2184 /**< Alloc ID Priority used in case of Extended DBA mode */
2185 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2186 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002187
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002188 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002189 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002190 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 -05002191port_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 -08002192 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002193 }
Girish Gowdra96461052019-11-22 20:13:59 +05302194
2195 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
2196 if (err) {
2197 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2198port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
2199 return err;
2200 }
2201
2202 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
2203port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
2204
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002205 }
2206
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002207 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002208}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002209
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002210Status CreateTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2211 uint32_t intf_id = traffic_scheds->intf_id();
2212 uint32_t onu_id = traffic_scheds->onu_id();
2213 uint32_t uni_id = traffic_scheds->uni_id();
2214 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002215 std::string direction;
2216 unsigned int alloc_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002217 tech_profile::SchedulerConfig sched_config;
2218 tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002219 uint32_t priority;
2220 uint32_t weight;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002221 tech_profile::SchedulingPolicy sched_policy;
2222 tech_profile::TrafficShapingInfo traffic_shaping_info;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002223 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002224 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002225
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002226 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2227 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002228
2229 direction = GetDirection(traffic_sched.direction());
2230 if (direction.compare("direction-not-supported") == 0)
2231 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2232
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002233 alloc_id = traffic_sched.alloc_id();
2234 sched_config = traffic_sched.scheduler();
2235 additional_bw = sched_config.additional_bw();
2236 priority = sched_config.priority();
2237 weight = sched_config.weight();
2238 sched_policy = sched_config.sched_policy();
2239 traffic_shaping_info = traffic_sched.traffic_shaping_info();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002240 tech_profile_id = traffic_sched.tech_profile_id();
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002241 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002242 sched_policy, traffic_shaping_info, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002243 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002244 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002245 return bcm_to_grpc_err(err, "Failed to create scheduler");
2246 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002247 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002248 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002249}
Jonathan Davis70c21812018-07-19 15:32:10 -04002250
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002251bcmos_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 -04002252
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002253 bcmos_errno err;
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302254 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302255 bcmolt_status los_status;
Girish Gowdra96461052019-11-22 20:13:59 +05302256 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002257
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002258 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002259 bcmolt_itupon_alloc_cfg cfg;
2260 bcmolt_itupon_alloc_key key = { };
2261 key.pon_ni = intf_id;
2262 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302263 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002264
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002265 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002266 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2267 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002268 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2269 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002270 return err;
2271 }
Girish Gowdra96461052019-11-22 20:13:59 +05302272
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302273 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302274 if (err == BCM_ERR_OK) {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302275 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_OFF) {
2276 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 +05302277 intf_id);
2278 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2279 if (err) {
2280 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2281 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
2282 return err;
2283 }
2284 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302285 else if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_ON) {
2286 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is enabled but LoS status is ON, not waiting for alloc cfg clear response\n",
2287 intf_id);
2288 }
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302289 else if (state == BCMOLT_INTERFACE_STATE_INACTIVE) {
2290 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is disabled, not waiting for alloc cfg clear response\n",
2291 intf_id);
2292 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302293 } else {
2294 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 +05302295 intf_id, bcmos_strerror(err));
Girish Gowdra96461052019-11-22 20:13:59 +05302296 return err;
2297 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002298 } else if (direction == downstream) {
2299 bcmolt_tm_sched_cfg cfg;
2300 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002301
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002302 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2303 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302304 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002305 } else {
2306 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2307 return BCM_ERR_OK;
2308 }
Girish Gowdra96461052019-11-22 20:13:59 +05302309
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002310 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2311 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2312 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002313 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002314intf_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 +00002315 return err;
2316 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002317 }
2318
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002319 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d, tech_profile_id %d\n",
2320 direction.c_str(), sched_id, intf_id, onu_id, tech_profile_id);
2321 free_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002322 return BCM_ERR_OK;
2323}
2324
2325Status RemoveTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2326 uint32_t intf_id = traffic_scheds->intf_id();
2327 uint32_t onu_id = traffic_scheds->onu_id();
2328 uint32_t uni_id = traffic_scheds->uni_id();
2329 std::string direction;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002330 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002331 bcmos_errno err;
2332
2333 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2334 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002335
2336 direction = GetDirection(traffic_sched.direction());
2337 if (direction.compare("direction-not-supported") == 0)
2338 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2339
2340 int alloc_id = traffic_sched.alloc_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002341 int tech_profile_id = traffic_sched.tech_profile_id();
2342 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002343 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002344 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002345 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2346 }
2347 }
2348 return Status::OK;
2349}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002350
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002351bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2352 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002353 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002354 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2355 bcmolt_tm_qmp_key tm_qmp_key;
2356 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002357
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002358 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2359 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002360 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed tm queue mapping profile count is 16.\n");
2361 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002362 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002363
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002364 tm_qmp_key.id = tm_qmp_id;
2365 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2366 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2367 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002368
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002369 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2370 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2371 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002372 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2373 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002374
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002375 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002376 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002377 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2378 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002379 return err;
2380 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002381
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002382 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2383 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002384 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002385}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002386
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002387bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2388 bcmos_errno err;
2389 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2390 bcmolt_tm_qmp_key tm_qmp_key;
2391 tm_qmp_key.id = tm_qmp_id;
2392
2393 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2394 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2395 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002396 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2397 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002398 return err;
2399 }
2400
2401 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2402 tm_qmp_key.id);
2403 return BCM_ERR_OK;
2404}
2405
2406bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2407 bcmos_errno err;
2408
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002409 /* Create default queues on the given PON/NNI scheduler */
2410 for (int queue_id = 0; queue_id < NUMBER_OF_DEFAULT_INTERFACE_QUEUES; queue_id++) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002411 bcmolt_tm_queue_cfg tm_queue_cfg;
2412 bcmolt_tm_queue_key tm_queue_key = {};
2413 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2414 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002415 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2416 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2417 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002418
2419 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2420 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2421 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2422
2423 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2424 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002425 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", \
2426 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 +00002427 return err;
2428 }
2429
2430 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2431 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2432 }
2433 return BCM_ERR_OK;
2434}
2435
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002436bcmos_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 +00002437 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 +00002438 bcmos_errno err;
2439 bcmolt_tm_queue_cfg cfg;
2440 bcmolt_tm_queue_key key = { };
2441 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 +00002442gemport_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 +00002443
2444 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002445 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002446
2447 if (priority > 7) {
2448 return BCM_ERR_RANGE;
2449 }
2450
2451 /* FIXME: The upstream queues have to be created once only.
2452 The upstream queues on the NNI scheduler are shared by all subscribers.
2453 When the first scheduler comes in, the queues get created, and are re-used by all others.
2454 Also, these queues should be present until the last subscriber exits the system.
2455 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2456
2457 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2458 for each GEM in TECH PROFILE */
2459 key.id = queue_id_list[priority];
2460
2461 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2462 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2463 key.id = 0;
2464 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2465 }
2466 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2467 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2468 }
2469 else {
2470 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2471 }
2472
2473 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2474
2475 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2476 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
2477
2478 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2479 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002480 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002481sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, tech_profile_id %d, err = %s\n", \
2482 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 +00002483 return err;
2484 }
2485
2486 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 +00002487intf_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 +00002488 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002489}
2490
2491Status CreateTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2492 uint32_t intf_id = traffic_queues->intf_id();
2493 uint32_t onu_id = traffic_queues->onu_id();
2494 uint32_t uni_id = traffic_queues->uni_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002495 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002496 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002497 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002498 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002499 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 +00002500
2501 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2502 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2503 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2504 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2505 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
2506
2507 direction = GetDirection(traffic_queue.direction());
2508 if (direction.compare("direction-not-supported") == 0)
2509 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2510
2511 queues_priority_q[i] = traffic_queue.priority();
2512 queues_pbit_map[i] = traffic_queue.pbit_map();
2513 }
2514
2515 std::vector<uint32_t> tmq_map_profile(8, 0);
2516 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2517 queues_priority_q, COUNT_OF(queues_priority_q));
2518 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002519 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002520
2521 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2522 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002523 err = CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2524 if (err != BCM_ERR_OK) {
2525 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2526 return bcm_to_grpc_err(err, "Failed to create tm queue mapping profile");
2527 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002528 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2529 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2530 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2531 }
2532 }
2533
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002534 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2535 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002536
2537 direction = GetDirection(traffic_queue.direction());
2538 if (direction.compare("direction-not-supported") == 0)
2539 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2540
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002541 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 +00002542
Girish Gowdruf26cf882019-05-01 23:47:58 -07002543 // If the queue exists already, lets not return failure and break the loop.
2544 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002545 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002546 return bcm_to_grpc_err(err, "Failed to create queue");
2547 }
2548 }
2549 return Status::OK;
2550}
2551
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002552bcmos_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 +00002553 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 +00002554 bcmolt_tm_queue_cfg cfg;
2555 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002556 bcmos_errno err;
2557
2558 if (direction == downstream) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002559 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2560 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 +00002561 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002562 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002563 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 -08002564 return BCM_ERR_OK;
2565 }
2566 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002567 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2568 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002569 return BCM_ERR_OK;
2570 }
2571
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002572 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2573 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2574 // Reset the queue id to 0 when using fixed queue.
2575 key.id = 0;
2576 }
2577 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2578 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2579 }
2580 else {
2581 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2582 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002583
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002584 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2585 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002586 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002587 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, queue_id %d, sched_id %d, \
2588tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n",
2589 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 -08002590 return err;
2591 }
2592
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002593 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2594intf_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 -08002595
2596 return BCM_ERR_OK;
2597}
2598
2599Status RemoveTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2600 uint32_t intf_id = traffic_queues->intf_id();
2601 uint32_t onu_id = traffic_queues->onu_id();
2602 uint32_t uni_id = traffic_queues->uni_id();
2603 uint32_t port_no = traffic_queues->port_no();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002604 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002605 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002606 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002607 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002608 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 +00002609
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002610 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2611 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002612
2613 direction = GetDirection(traffic_queue.direction());
2614 if (direction.compare("direction-not-supported") == 0)
2615 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2616
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002617 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 -08002618 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002619 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002620 return bcm_to_grpc_err(err, "Failed to remove queue");
2621 }
Jonathan Davis70c21812018-07-19 15:32:10 -04002622 }
2623
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002624 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 +00002625 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002626 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002627
2628 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
2629 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002630 err = RemoveTrafficQueueMappingProfile(tm_qmp_id);
2631 if (err != BCM_ERR_OK) {
2632 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2633 return bcm_to_grpc_err(err, "Failed to remove tm queue mapping profile");
2634 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002635 }
2636 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002637 clear_qos_type(intf_id, onu_id, uni_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04002638 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04002639}
Jason Huangbf45ffb2019-10-30 17:29:02 +08002640
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002641Status PerformGroupOperation_(const openolt::Group *group_cfg) {
2642
2643 bcmos_errno err;
2644 bcmolt_group_key key = {};
2645 bcmolt_group_cfg grp_cfg_obj;
2646 bcmolt_group_members_update grp_mem_upd;
2647 bcmolt_members_update_command grp_mem_upd_cmd;
2648 bcmolt_group_member_info member_info = {};
2649 bcmolt_group_member_info_list_u8 members = {};
2650 bcmolt_intf_ref interface_ref = {};
2651 bcmolt_egress_qos egress_qos = {};
2652 bcmolt_tm_sched_ref tm_sched_ref = {};
2653 bcmolt_action a_val = {};
2654
2655 uint32_t group_id = group_cfg->group_id();
2656
2657 OPENOLT_LOG(INFO, openolt_log_id, "PerformGroupOperation request received for Group %d\n", group_id);
2658
2659 if (group_id >= 0) {
2660 key.id = group_id;
2661 }
2662 else {
2663 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
2664 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
2665 }
2666
2667 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2668 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
2669
2670 OPENOLT_LOG(INFO, openolt_log_id, "Checking if Group %d exists...\n",group_id);
2671
2672 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
2673 if (err != BCM_ERR_OK) {
2674 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
2675 return bcm_to_grpc_err(err, "Error in querying group");
2676 }
2677
2678 members.len = group_cfg->members_size();
2679
2680 // IMPORTANT: A member cannot be added to a group if the group type is not determined.
2681 // Group type is determined after a flow is assigned to it.
2682 // Therefore, a group must be created first, then a flow (with multicast type) must be assigned to it.
2683 // Only then we can add members to the group.
2684
2685 // if group does not exist, create it and return.
2686 if (grp_cfg_obj.data.state == BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
2687
2688 if (members.len != 0) {
2689 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);
2690 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Non-empty member list given for non-existent group");
2691 } else {
2692
2693 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2694 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, cookie, key.id);
2695
2696 /* Setting group actions and action parameters, if any.
2697 Only remove_outer_tag and translate_inner_tag actions and i_vid action parameter
2698 are supported for multicast groups in BAL 3.1.
2699 */
2700 const ::openolt::Action& action = group_cfg->action();
2701 const ::openolt::ActionCmd &cmd = action.cmd();
2702
2703 bcmolt_action_cmd_id cmd_bmask = BCMOLT_ACTION_CMD_ID_NONE;
2704 if (cmd.remove_outer_tag()) {
2705 OPENOLT_LOG(INFO, openolt_log_id, "Action remove_outer_tag applied to Group %d.\n", group_id);
2706 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
2707 }
2708
2709 if (cmd.translate_inner_tag()) {
2710 OPENOLT_LOG(INFO, openolt_log_id, "Action translate_inner_tag applied to Group %d.\n", group_id);
2711 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG);
2712 }
2713
2714 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, cmd_bmask);
2715
2716 if (action.i_vid()) {
2717 OPENOLT_LOG(INFO, openolt_log_id, "Setting action parameter i_vid=%d for Group %d.\n", action.i_vid(), group_id);
2718 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
2719 }
2720
2721 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, action, a_val);
2722
2723 // Create group
2724 err = bcmolt_cfg_set(dev_id, &(grp_cfg_obj.hdr));
2725
2726 if (BCM_ERR_OK != err) {
2727 BCM_LOG(ERROR, openolt_log_id, "Failed to create Group %d, err = %s (%d)\n", key.id, bcmos_strerror(err), err);
2728 return bcm_to_grpc_err(err, "Error in creating group");
2729 }
2730
2731 BCM_LOG(INFO, openolt_log_id, "Group %d has been created and configured with empty member list.\n", key.id);
2732 return Status::OK;
2733 }
2734 }
2735
2736 // The group already exists. Continue configuring it according to the update member command.
2737
2738 OPENOLT_LOG(INFO, openolt_log_id, "Configuring existing Group %d.\n",group_id);
2739
2740 // MEMBER LIST CONSTRUCTION
2741 // Note that members.len can be 0 here. if the group already exists and the command is SET then sending
2742 // empty list to the group is a legit operation and this actually empties the member list.
2743 members.arr = (bcmolt_group_member_info*)bcmos_calloc((members.len)*sizeof(bcmolt_group_member_info));
2744
2745 if (!members.arr) {
2746 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to allocate memory for group member list.\n");
2747 return grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "Memory exhausted during member list creation");
2748 }
2749
2750 /* SET GROUP MEMBERS UPDATE COMMAND */
2751 openolt::Group::GroupMembersCommand command = group_cfg->command();
2752 switch(command) {
2753 case openolt::Group::SET_MEMBERS :
2754 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_SET;
2755 OPENOLT_LOG(INFO, openolt_log_id, "Setting %d members for Group %d.\n", members.len, group_id);
2756 break;
2757 case openolt::Group::ADD_MEMBERS :
2758 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_ADD;
2759 OPENOLT_LOG(INFO, openolt_log_id, "Adding %d members to Group %d.\n", members.len, group_id);
2760 break;
2761 case openolt::Group::REMOVE_MEMBERS :
2762 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_REMOVE;
2763 OPENOLT_LOG(INFO, openolt_log_id, "Removing %d members from Group %d.\n", members.len, group_id);
2764 break;
2765 default :
2766 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid value %d for group member command.\n", command);
2767 bcmos_free(members.arr);
2768 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group member command");
2769 }
2770
2771 // SET MEMBERS LIST
2772 for (int i = 0; i < members.len; i++) {
2773
2774 if (command == openolt::Group::REMOVE_MEMBERS) {
2775 OPENOLT_LOG(INFO, openolt_log_id, "Removing group member %d from group %d\n",i,key.id);
2776 } else {
2777 OPENOLT_LOG(INFO, openolt_log_id, "Adding group member %d to group %d\n",i,key.id);
2778 }
2779
2780 openolt::GroupMember *member = (openolt::GroupMember *) &group_cfg->members()[i];
2781
2782 // Set member interface type
2783 openolt::GroupMember::InterfaceType if_type = member->interface_type();
2784 switch(if_type){
2785 case openolt::GroupMember::PON :
2786 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_PON);
2787 OPENOLT_LOG(INFO, openolt_log_id, "Interface type PON is assigned to GroupMember %d\n",i);
2788 break;
2789 case openolt::GroupMember::EPON_1G_PATH :
2790 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_1_G);
2791 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_1G is assigned to GroupMember %d\n",i);
2792 break;
2793 case openolt::GroupMember::EPON_10G_PATH :
2794 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_10_G);
2795 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_10G is assigned to GroupMember %d\n",i);
2796 break;
2797 default :
2798 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid interface type value %d for GroupMember %d.\n",if_type,i);
2799 bcmos_free(members.arr);
2800 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface type for a group member");
2801 }
2802
2803 // Set member interface id
2804 if (member->interface_id() >= 0) {
2805 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_id, member->interface_id());
2806 OPENOLT_LOG(INFO, openolt_log_id, "Interface %d is assigned to GroupMember %d\n", member->interface_id(), i);
2807 } else {
2808 bcmos_free(members.arr);
2809 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface id for a group member");
2810 }
2811
2812 // Set member interface_ref
2813 BCMOLT_FIELD_SET(&member_info, group_member_info, intf, interface_ref);
2814
2815 // Set member gem_port_id. This must be a multicast gemport.
2816 if (member->gem_port_id() >= 0) {
2817 BCMOLT_FIELD_SET(&member_info, group_member_info, svc_port_id, member->gem_port_id());
2818 OPENOLT_LOG(INFO, openolt_log_id, "GEM Port %d is assigned to GroupMember %d\n", member->gem_port_id(), i);
2819 } else {
2820 bcmos_free(members.arr);
2821 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid gem port id for a group member");
2822 }
2823
2824 // Set member scheduler id and queue_id
2825 uint32_t tm_sched_id = get_default_tm_sched_id(member->interface_id(), downstream);
2826 OPENOLT_LOG(INFO, openolt_log_id, "Scheduler %d is assigned to GroupMember %d\n", tm_sched_id, i);
2827 BCMOLT_FIELD_SET(&tm_sched_ref, tm_sched_ref, id, tm_sched_id);
2828 BCMOLT_FIELD_SET(&egress_qos, egress_qos, tm_sched, tm_sched_ref);
2829
2830 // We assume that all multicast traffic destined to a PON port is using the same fixed queue.
2831 uint32_t tm_queue_id;
2832 if (member->priority() >= 0 && member->priority() < NUMBER_OF_DEFAULT_INTERFACE_QUEUES) {
2833 tm_queue_id = queue_id_list[member->priority()];
2834 OPENOLT_LOG(INFO, openolt_log_id, "Queue %d is assigned to GroupMember %d\n", tm_queue_id, i);
2835 BCMOLT_FIELD_SET(&egress_qos, egress_qos, type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2836 BCMOLT_FIELD_SET(&egress_qos.u.fixed_queue, egress_qos_fixed_queue, queue_id, tm_queue_id);
2837 } else {
2838 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid fixed queue priority/ID %d for GroupMember %d\n", member->priority(), i);
2839 bcmos_free(members.arr);
2840 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid queue priority for a group member");
2841 }
2842
2843 BCMOLT_FIELD_SET(&member_info, group_member_info, egress_qos, egress_qos);
2844 BCMOLT_ARRAY_ELEM_SET(&(members), i, member_info);
2845 }
2846
2847 BCMOLT_OPER_INIT(&grp_mem_upd, group, members_update, key);
2848 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.members, members);
2849 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.command, grp_mem_upd_cmd);
2850
2851 err = bcmolt_oper_submit(dev_id, &(grp_mem_upd.hdr));
2852 bcmos_free(members.arr);
2853
2854 if (BCM_ERR_OK != err) {
2855 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);
2856 return bcm_to_grpc_err(err, "Failed to submit members update operation for the group");
2857 }
2858
2859 OPENOLT_LOG(INFO, openolt_log_id, "Successfully submitted members update operation for Group %d\n", key.id);
2860
2861 return Status::OK;
2862}
Burak Gurdageb4ca2e2020-06-15 07:48:26 +00002863
2864Status DeleteGroup_(uint32_t group_id) {
2865
2866 bcmos_errno err = BCM_ERR_OK;
2867 bcmolt_group_cfg grp_cfg_obj;
2868 bcmolt_group_key key = {};
2869
2870
2871 OPENOLT_LOG(INFO, openolt_log_id, "Delete request received for group %d\n", group_id);
2872
2873 if (group_id >= 0) {
2874 key.id = group_id;
2875 } else {
2876 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
2877 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
2878 }
2879
2880 /* init the BAL INIT API */
2881 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2882
2883 OPENOLT_LOG(DEBUG, openolt_log_id, "Checking if group %d exists...\n",group_id);
2884
2885 // CONFIGURE GROUP MEMBERS
2886 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
2887 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
2888
2889 if (err != BCM_ERR_OK) {
2890 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
2891 return bcm_to_grpc_err(err, "Error in querying group");
2892 }
2893
2894 if (grp_cfg_obj.data.state != BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
2895 OPENOLT_LOG(DEBUG, openolt_log_id, "Group %d exists. Will be deleted.\n",group_id);
2896 err = bcmolt_cfg_clear(dev_id, &(grp_cfg_obj.hdr));
2897 if (err != BCM_ERR_OK) {
2898 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d cannot be deleted err = %s (%d).\n", group_id, bcmos_strerror(err), err);
2899 return bcm_to_grpc_err(err, "Failed to delete group");;
2900 }
2901 } else {
2902 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d does not exist.\n", group_id);
2903 return Status(grpc::StatusCode::NOT_FOUND, "Group not found");
2904 }
2905
2906 OPENOLT_LOG(INFO, openolt_log_id, "Group %d has been deleted successfully.\n", group_id);
2907 return Status::OK;
Jason Huang1d9cfce2020-05-20 22:58:47 +08002908}
2909
2910Status GetLogicalOnuDistanceZero_(uint32_t intf_id, openolt::OnuLogicalDistance* response) {
2911 bcmos_errno err = BCM_ERR_OK;
2912 uint32_t mld = 0;
2913 double LD0;
2914
2915 err = getOnuMaxLogicalDistance(intf_id, &mld);
2916 if (err != BCM_ERR_OK) {
2917 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
2918 }
2919
2920 LD0 = LOGICAL_DISTANCE(mld*1000, MINIMUM_ONU_RESPONSE_RANGING_TIME, ONU_BIT_TRANSMISSION_DELAY);
2921 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance zero is %f, (PON %d)\n", LD0, intf_id);
2922 response->set_intf_id(intf_id);
2923 response->set_logical_onu_distance_zero(LD0);
2924
2925 return Status::OK;
2926}
2927
2928Status GetLogicalOnuDistance_(uint32_t intf_id, uint32_t onu_id, openolt::OnuLogicalDistance* response) {
2929 bcmos_errno err = BCM_ERR_OK;
2930 bcmolt_itu_onu_params itu = {};
2931 bcmolt_onu_cfg onu_cfg;
2932 bcmolt_onu_key onu_key = {};
2933 uint32_t mld = 0;
2934 double LDi;
2935
2936 onu_key.pon_ni = intf_id;
2937 onu_key.onu_id = onu_id;
2938
2939 err = getOnuMaxLogicalDistance(intf_id, &mld);
2940 if (err != BCM_ERR_OK) {
2941 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
2942 }
2943
2944 /* Initialize the API struct. */
2945 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
2946 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
2947 BCMOLT_FIELD_SET_PRESENT(&itu, itu_onu_params, ranging_time);
2948 BCMOLT_FIELD_SET(&onu_cfg.data, onu_cfg_data, itu, itu);
2949 #ifdef TEST_MODE
2950 // It is impossible to mock the setting of onu_cfg.data.onu_state because
2951 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
2952 // set the onu_cfg.data.onu_state. So a new stub function is created and address
2953 // of onu_cfg is passed. This is one-of case where we need to add test specific
2954 // code in production code.
2955 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
2956 #else
2957 /* Call API function. */
2958 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
2959 #endif
2960 if (err != BCM_ERR_OK) {
2961 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);
2962 return bcm_to_grpc_err(err, "Failed to retrieve ONU ranging time");
2963 }
2964
2965 if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_ACTIVE) {
2966 OPENOLT_LOG(ERROR, openolt_log_id, "ONU is not yet activated (PON %d, ONU id %d)\n", intf_id, onu_id);
2967 return bcm_to_grpc_err(BCM_ERR_PARM, "ONU is not yet activated\n");
2968 }
2969
2970 LDi = LOGICAL_DISTANCE(mld*1000, onu_cfg.data.itu.ranging_time, ONU_BIT_TRANSMISSION_DELAY);
2971 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance is %f, (PON %d, ONU id %d)\n", LDi, intf_id, onu_id);
2972 response->set_intf_id(intf_id);
2973 response->set_onu_id(onu_id);
2974 response->set_logical_onu_distance(LDi);
2975
2976 return Status::OK;
2977}