blob: bb2e4669c148ed712a09bfd2309a194fe2b0e5c5 [file] [log] [blame]
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001/*
Shivanagouda Malaginahallie707d612023-08-22 10:40:25 +00002 * Copyright 2018-2023 Open Networking Foundation (ONF) and the ONF Contributors
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
nikesh.krishnan331d38c2023-04-06 03:24:53 +053017#include <cerrno>
Shad Ansarib7b0ced2018-05-11 21:53:32 +000018#include <iostream>
19#include <memory>
20#include <string>
21
22#include "Queue.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000023#include <sstream>
Nicolas Palpacuer9c352082018-08-14 16:37:14 -040024#include <chrono>
25#include <thread>
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080026#include <bitset>
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000027#include <inttypes.h>
Jason Huangbf45ffb2019-10-30 17:29:02 +080028#include <unistd.h>
Jason Huang09b73ea2020-01-08 17:52:05 +080029#include <sys/socket.h>
30#include <netinet/in.h>
31#include <arpa/inet.h>
Shad Ansarib7b0ced2018-05-11 21:53:32 +000032
Craig Lutgen88a22ad2018-10-04 12:30:46 -050033#include "device.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000034#include "core.h"
Girish Gowdraddf9a162020-01-27 12:56:27 +053035#include "core_data.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000036#include "indications.h"
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -040037#include "stats_collection.h"
Nicolas Palpacuer73222e02018-07-16 12:20:26 -040038#include "error_format.h"
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -040039#include "state.h"
Girish Gowdraddf9a162020-01-27 12:56:27 +053040#include "core_utils.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000041
42extern "C"
43{
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000044#include <bcmolt_api.h>
45#include <bcmolt_host_api.h>
46#include <bcmolt_api_model_supporting_enums.h>
47
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000048#include <bcmolt_api_conn_mgr.h>
49//CLI header files
50#include <bcmcli_session.h>
51#include <bcmcli.h>
52#include <bcm_api_cli.h>
53
54#include <bcmos_common.h>
55#include <bcm_config.h>
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -040056// FIXME : dependency problem
57// #include <bcm_common_gpon.h>
Nicolas Palpacuer967438f2018-09-07 14:41:54 -040058// #include <bcm_dev_log_task.h>
Shad Ansarib7b0ced2018-05-11 21:53:32 +000059}
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000060
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000061static std::string intf_technologies[MAX_SUPPORTED_PON];
Craig Lutgen88a22ad2018-10-04 12:30:46 -050062static const std::string UNKNOWN_TECH("unknown");
Craig Lutgenb2601f02018-10-23 13:04:31 -050063static const std::string MIXED_TECH("mixed");
64static std::string board_technology(UNKNOWN_TECH);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000065static std::string chip_family(UNKNOWN_TECH);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000066static std::string firmware_version = "Openolt.2019.07.01";
Nicolas Palpacuerdff96792018-09-06 14:59:32 -040067
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080068static bcmos_errno CreateSched(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
Girish Gowdra252f4972020-09-07 21:24:01 -070069 uint32_t port_no, uint32_t alloc_id, ::tech_profile::AdditionalBW additional_bw, uint32_t weight, \
70 uint32_t priority, ::tech_profile::SchedulingPolicy sched_policy,
71 ::tech_profile::TrafficShapingInfo traffic_shaping_info, uint32_t tech_profile_id);
Burak Gurdag2f2618c2020-04-23 13:20:30 +000072static bcmos_errno RemoveSched(int intf_id, int onu_id, int uni_id, int alloc_id, std::string direction, int tech_profile_id);
Sridhar Ravindra57d7eb92025-06-04 13:39:43 +053073static bcmos_errno CreateQueue(std::string direction, uint32_t nni_intf_id, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +000074 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 -050075static 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 +000076 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 +000077static bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction);
78static bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction);
Orhan Kupusogluec57af02021-05-12 12:38:17 +000079static const std::chrono::milliseconds ONU_RSSI_COMPLETE_WAIT_TIMEOUT = std::chrono::seconds(10);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000080
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000081inline const char *get_flow_acton_command(uint32_t command) {
82 char actions[200] = { };
83 char *s_actions_ptr = actions;
84 if (command & BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG) strcat(s_actions_ptr, "ADD_OUTER_TAG|");
85 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG) strcat(s_actions_ptr, "REMOVE_OUTER_TAG|");
86 if (command & BCMOLT_ACTION_CMD_ID_XLATE_OUTER_TAG) strcat(s_actions_ptr, "TRANSLATE_OUTER_TAG|");
87 if (command & BCMOLT_ACTION_CMD_ID_ADD_INNER_TAG) strcat(s_actions_ptr, "ADD_INNTER_TAG|");
88 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_INNER_TAG) strcat(s_actions_ptr, "REMOVE_INNER_TAG|");
89 if (command & BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG) strcat(s_actions_ptr, "TRANSLATE_INNER_TAG|");
90 if (command & BCMOLT_ACTION_CMD_ID_REMARK_OUTER_PBITS) strcat(s_actions_ptr, "REMOVE_OUTER_PBITS|");
91 if (command & BCMOLT_ACTION_CMD_ID_REMARK_INNER_PBITS) strcat(s_actions_ptr, "REMAKE_INNER_PBITS|");
92 return s_actions_ptr;
93}
94
kesavandc1f2db92020-08-31 15:32:06 +053095bcmolt_stat_alarm_config set_stat_alarm_config(const config::OnuItuPonAlarm* request) {
Jason Huang5d9ab1a2020-04-15 16:53:49 +080096 bcmolt_stat_alarm_config alarm_cfg = {};
97 bcmolt_stat_alarm_trigger_config trigger_obj = {};
98 bcmolt_stat_alarm_soak_config soak_obj = {};
99
100 switch (request->alarm_reporting_condition()) {
kesavandc1f2db92020-08-31 15:32:06 +0530101 case config::OnuItuPonAlarm::RATE_THRESHOLD:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800102 trigger_obj.type = BCMOLT_STAT_CONDITION_TYPE_RATE_THRESHOLD;
103 BCMOLT_FIELD_SET(&trigger_obj.u.rate_threshold, stat_alarm_trigger_config_rate_threshold,
104 rising, request->rate_threshold_config().rate_threshold_rising());
105 BCMOLT_FIELD_SET(&trigger_obj.u.rate_threshold, stat_alarm_trigger_config_rate_threshold,
106 falling, request->rate_threshold_config().rate_threshold_falling());
107 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, active_soak_time,
108 request->rate_threshold_config().soak_time().active_soak_time());
109 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, clear_soak_time,
110 request->rate_threshold_config().soak_time().clear_soak_time());
111 break;
kesavandc1f2db92020-08-31 15:32:06 +0530112 case config::OnuItuPonAlarm::RATE_RANGE:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800113 trigger_obj.type = BCMOLT_STAT_CONDITION_TYPE_RATE_RANGE;
114 BCMOLT_FIELD_SET(&trigger_obj.u.rate_range, stat_alarm_trigger_config_rate_range, upper,
115 request->rate_range_config().rate_range_upper());
116 BCMOLT_FIELD_SET(&trigger_obj.u.rate_range, stat_alarm_trigger_config_rate_range, lower,
117 request->rate_range_config().rate_range_lower());
118 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, active_soak_time,
119 request->rate_range_config().soak_time().active_soak_time());
120 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, clear_soak_time,
121 request->rate_range_config().soak_time().clear_soak_time());
122 break;
kesavandc1f2db92020-08-31 15:32:06 +0530123 case config::OnuItuPonAlarm::VALUE_THRESHOLD:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800124 trigger_obj.type = BCMOLT_STAT_CONDITION_TYPE_VALUE_THRESHOLD;
125 BCMOLT_FIELD_SET(&trigger_obj.u.value_threshold, stat_alarm_trigger_config_value_threshold,
126 limit, request->value_threshold_config().threshold_limit());
127 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, active_soak_time,
128 request->value_threshold_config().soak_time().active_soak_time());
129 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, clear_soak_time,
130 request->value_threshold_config().soak_time().clear_soak_time());
131 break;
132 default:
133 OPENOLT_LOG(ERROR, openolt_log_id, "unsupported alarm reporting condition = %u\n", request->alarm_reporting_condition());
134 // For now just log the error and not return error. We can handle this scenario in the future.
135 break;
136 }
137
138 BCMOLT_FIELD_SET(&alarm_cfg, stat_alarm_config, trigger, trigger_obj);
139 BCMOLT_FIELD_SET(&alarm_cfg, stat_alarm_config, soak, soak_obj);
140
141 return alarm_cfg;
142}
143
kesavandc1f2db92020-08-31 15:32:06 +0530144Status OnuItuPonAlarmSet_(const config::OnuItuPonAlarm* request) {
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800145 bcmos_errno err;
146 bcmolt_onu_itu_pon_stats_cfg stat_cfg; /* declare main API struct */
147 bcmolt_onu_key key = {}; /* declare key */
148 bcmolt_stat_alarm_config errors_cfg = {};
149
150 key.pon_ni = request->pon_ni();
151 key.onu_id = request->onu_id();
152
153 /* Initialize the API struct. */
154 BCMOLT_STAT_CFG_INIT(&stat_cfg, onu, itu_pon_stats, key);
155
156 /*
157 1. BCMOLT_STAT_CONDITION_TYPE_NONE = 0, The alarm is disabled.
158 2. BCMOLT_STAT_CONDITION_TYPE_RATE_THRESHOLD = 1, The alarm is triggered if the stats delta value between samples
159 crosses the configured threshold boundary.
160 rising: The alarm is raised if the stats delta value per second becomes greater than this threshold level.
161 falling: The alarm is cleared if the stats delta value per second becomes less than this threshold level.
162 3. BCMOLT_STAT_CONDITION_TYPE_RATE_RANGE = 2, The alarm is triggered if the stats delta value between samples
163 deviates from the configured range.
164 upper: The alarm is raised if the stats delta value per second becomes greater than this upper level.
165 lower: The alarm is raised if the stats delta value per second becomes less than this lower level.
166 4. BCMOLT_STAT_CONDITION_TYPE_VALUE_THRESHOLD = 3, The alarm is raised if the stats sample value becomes greater
167 than this level. The alarm is cleared when the host read the stats.
168 limit: The alarm is raised if the stats sample value becomes greater than this level.
169 The alarm is cleared when the host clears the stats.
170
171 active_soak_time: If the alarm condition is raised and stays in the raised state for at least this amount
172 of time (unit=seconds), the alarm indication is sent to the host.
173 The OLT delays the alarm indication no less than this delay period.
174 It can be delayed more than this period because of the statistics sampling interval.
175 clear_soak_time: After the alarm is raised, if it is cleared and stays in the cleared state for at least
176 this amount of time (unit=seconds), the alarm indication is sent to the host.
177 The OLT delays the alarm indication no less than this delay period. It can be delayed more
178 than this period because of the statistics sampling interval.
179 */
180
181 errors_cfg = set_stat_alarm_config(request);
182
183 switch (request->alarm_id()) {
kesavandc1f2db92020-08-31 15:32:06 +0530184 case config::OnuItuPonAlarm_AlarmID::OnuItuPonAlarm_AlarmID_RDI_ERRORS:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800185 //set the rdi_errors alarm
186 BCMOLT_FIELD_SET(&stat_cfg.data, onu_itu_pon_stats_cfg_data, rdi_errors, errors_cfg);
187 break;
188 default:
189 OPENOLT_LOG(ERROR, openolt_log_id, "could not find the alarm id %d\n", request->alarm_id());
190 return bcm_to_grpc_err(BCM_ERR_PARM, "the alarm id is wrong");
191 }
192
193 err = bcmolt_stat_cfg_set(dev_id, &stat_cfg.hdr);
194 if (err != BCM_ERR_OK) {
195 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",
196 request->alarm_id(), key.pon_ni, key.onu_id, bcmos_strerror(err));
197 return bcm_to_grpc_err(err, "set Onu ITU PON stats alarm faild");
198 } else {
199 OPENOLT_LOG(INFO, openolt_log_id, "set onu itu pon stats alarm %d successfully, pon_ni %d, onu_id %d\n",
200 request->alarm_id(), key.pon_ni, key.onu_id);
201 }
202
203 return Status::OK;
204}
205
Girish Gowdra252f4972020-09-07 21:24:01 -0700206Status GetDeviceInfo_(::openolt::DeviceInfo* device_info) {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500207 device_info->set_vendor(VENDOR_ID);
208 device_info->set_model(MODEL_ID);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400209 device_info->set_hardware_version("");
210 device_info->set_firmware_version(firmware_version);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500211 device_info->set_pon_ports(num_of_pon_ports);
Sridhar Ravindra57d7eb92025-06-04 13:39:43 +0530212 device_info->set_nni_ports(num_of_nni_ports);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500213
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800214 char serial_number[OPENOLT_FIELD_LEN];
215 memset(serial_number, '\0', OPENOLT_FIELD_LEN);
216 openolt_read_sysinfo("Serial Number", serial_number);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000217 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device serial number %s\n", serial_number);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800218 device_info->set_device_serial_number(serial_number);
Burak Gurdag30db4822021-03-10 21:30:01 +0000219 device_info->set_previously_connected(state.previously_connected());
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800220
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700221 char device_id[OPENOLT_FIELD_LEN];
222 memset(device_id, '\0', OPENOLT_FIELD_LEN);
Humera Kouser6143c9e2020-06-17 22:37:31 +0530223
224 if (grpc_server_interface_name != NULL) {
225 if (get_intf_mac(grpc_server_interface_name, device_id, sizeof(device_id)) != NULL)
226 {
227 OPENOLT_LOG(INFO, openolt_log_id, "Fetched mac address %s of an interface %s\n", device_id, grpc_server_interface_name);
228 }
229 else
230 {
231 OPENOLT_LOG(ERROR, openolt_log_id, "Mac address of an interface %s is NULL\n", grpc_server_interface_name);
232 }
233 }
234 else
235 {
236 openolt_read_sysinfo("MAC", device_id);
237 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device mac address %s\n", device_id);
238 }
239
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700240 device_info->set_device_id(device_id);
Girish Gowdra252f4972020-09-07 21:24:01 -0700241 std::map<std::string, ::openolt::DeviceInfo::DeviceResourceRanges*> ranges;
Craig Lutgenb2601f02018-10-23 13:04:31 -0500242 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
243 std::string intf_technology = intf_technologies[intf_id];
Girish Gowdra252f4972020-09-07 21:24:01 -0700244 ::openolt::DeviceInfo::DeviceResourceRanges *range = ranges[intf_technology];
Craig Lutgenb2601f02018-10-23 13:04:31 -0500245 if(range == nullptr) {
246 range = device_info->add_ranges();
247 ranges[intf_technology] = range;
248 range->set_technology(intf_technology);
249
Girish Gowdra252f4972020-09-07 21:24:01 -0700250 ::openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
Craig Lutgenb2601f02018-10-23 13:04:31 -0500251
Girish Gowdra252f4972020-09-07 21:24:01 -0700252 pool = range->add_pools();
253 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
254 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
255 pool->set_start(ONU_ID_START);
256 pool->set_end(ONU_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500257
Girish Gowdra252f4972020-09-07 21:24:01 -0700258 pool = range->add_pools();
259 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
260 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
261 pool->set_start(ALLOC_ID_START);
Girish Gowdraeec0fc92021-05-12 15:37:55 -0700262 pool->set_end(ALLOC_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500263
Girish Gowdra252f4972020-09-07 21:24:01 -0700264 pool = range->add_pools();
265 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
266 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
267 pool->set_start(GEM_PORT_ID_START);
268 pool->set_end(GEM_PORT_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500269
Girish Gowdra252f4972020-09-07 21:24:01 -0700270 pool = range->add_pools();
271 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
272 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
273 pool->set_start(FLOW_ID_START);
274 pool->set_end(FLOW_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500275 }
276
277 range->add_intf_ids(intf_id);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500278 }
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400279
280 // FIXME: Once dependency problem is fixed
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500281 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400282 // device_info->set_onu_id_end(XGPON_NUM_OF_ONUS - 1);
283 // device_info->set_alloc_id_start(1024);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500284 // device_info->set_alloc_id_end(XGPON_NUM_OF_ALLOC_IDS * num_of_pon_ports ? - 1);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400285 // device_info->set_gemport_id_start(XGPON_MIN_BASE_SERVICE_PORT_ID);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500286 // device_info->set_gemport_id_end(XGPON_NUM_OF_GEM_PORT_IDS_PER_PON * num_of_pon_ports ? - 1);
287 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400288
289 return Status::OK;
290}
291
Thiyagarajan Subramani3e8bfd92021-04-26 15:07:14 +0530292void reset_pon_device(bcmolt_odid dev)
293{
294 bcmos_errno err;
295 bcmolt_device_reset oper;
296 bcmolt_device_key key = {.device_id = dev};
297
298 OPENOLT_LOG(INFO, openolt_log_id, "Reset PON device: %d\n", dev);
299
300 BCMOLT_OPER_INIT(&oper, device, reset, key);
301 err = bcmolt_oper_submit(dev_id, &oper.hdr);
302 if (err)
303 {
304 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to reset PON device(%d) failed, err = %s\n", dev, bcmos_strerror(err));
305 }else
306 {
307 OPENOLT_LOG(INFO, openolt_log_id, "Reset PON device(%d) success\n", dev);
308 }
309}
310
Shad Ansari627b5782018-08-13 22:49:32 +0000311Status Enable_(int argc, char *argv[]) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000312 bcmos_errno err;
313 bcmolt_host_init_parms init_parms = {};
314 init_parms.transport.type = BCM_HOST_API_CONN_LOCAL;
315 unsigned int failed_enable_device_cnt = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000316
Shad Ansariedef2132018-08-10 22:14:50 +0000317 if (!state.is_activated()) {
Shad Ansari627b5782018-08-13 22:49:32 +0000318
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500319 vendor_init();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000320 /* Initialize host subsystem */
321 err = bcmolt_host_init(&init_parms);
322 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500323 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to init OLT, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000324 return bcm_to_grpc_err(err, "Failed to init OLT");
325 }
326
327 bcmcli_session_parm mon_session_parm;
328 /* Create CLI session */
329 memset(&mon_session_parm, 0, sizeof(mon_session_parm));
330 mon_session_parm.get_prompt = openolt_cli_get_prompt_cb;
331 mon_session_parm.access_right = BCMCLI_ACCESS_ADMIN;
332 bcmos_errno rc = bcmcli_session_open(&mon_session_parm, &current_session);
333 BUG_ON(rc != BCM_ERR_OK);
334
335 /* API CLI */
336 bcm_openolt_api_cli_init(NULL, current_session);
337
338 /* Add quit command */
339 BCMCLI_MAKE_CMD_NOPARM(NULL, "quit", "Quit", bcm_cli_quit);
340
341 err = bcmolt_apiend_cli_init();
342 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500343 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to add apiend init, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000344 return bcm_to_grpc_err(err, "Failed to add apiend init");
345 }
346
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800347 bcmos_fastlock_init(&data_lock, 0);
Girish Gowdra252f4972020-09-07 21:24:01 -0700348 bcmos_fastlock_init(&acl_id_bitset_lock, 0);
349 bcmos_fastlock_init(&tm_sched_bitset_lock, 0);
350 bcmos_fastlock_init(&tm_qmp_bitset_lock, 0);
351 bcmos_fastlock_init(&flow_id_bitset_lock, 0);
352 bcmos_fastlock_init(&voltha_flow_to_device_flow_lock, 0);
Girish Gowdra96461052019-11-22 20:13:59 +0530353 bcmos_fastlock_init(&alloc_cfg_wait_lock, 0);
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +0530354 bcmos_fastlock_init(&gem_cfg_wait_lock, 0);
Girish Gowdra7a79dae2020-02-10 18:22:11 +0530355 bcmos_fastlock_init(&onu_deactivate_wait_lock, 0);
Girish Gowdra1935e6a2020-10-31 21:48:22 -0700356 bcmos_fastlock_init(&acl_packet_trap_handler_lock, 0);
Girish Gowdraeec0fc92021-05-12 15:37:55 -0700357 bcmos_fastlock_init(&symmetric_datapath_flow_id_lock, 0);
358 bcmos_fastlock_init(&pon_gem_to_onu_uni_map_lock, 0);
359
Girish Gowdra1935e6a2020-10-31 21:48:22 -0700360
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000361 OPENOLT_LOG(INFO, openolt_log_id, "Enable OLT - %s-%s\n", VENDOR_ID, MODEL_ID);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600362
Jason Huangbf45ffb2019-10-30 17:29:02 +0800363 //check BCM daemon is connected or not
364 Status status = check_connection();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000365 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800366 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000367 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800368 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000369 Status status = SubscribeIndication();
370 if (!status.ok()) {
371 OPENOLT_LOG(ERROR, openolt_log_id, "SubscribeIndication failed - %s : %s\n",
372 grpc_status_code_to_string(status.error_code()).c_str(),
373 status.error_message().c_str());
374 return status;
375 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800376
377 //check BAL state in initial stage
378 status = check_bal_ready();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000379 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800380 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000381 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800382 }
383
384 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000385 bcmos_errno err;
386 bcmolt_odid dev;
387 OPENOLT_LOG(INFO, openolt_log_id, "Enabling PON %d Devices ... \n", BCM_MAX_DEVS_PER_LINE_CARD);
388 for (dev = 0; dev < BCM_MAX_DEVS_PER_LINE_CARD; dev++) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400389 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000390 bcmolt_device_key dev_key = { };
391 dev_key.device_id = dev;
392 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
393 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Thiyagarajan Subramani4e62e172021-06-25 17:31:30 +0530394
Girish Gowdrab0337eb2022-03-25 16:44:21 -0700395 /* FIXME: Single Phoenix BAL patch is prepared for all three variants of Radisys OLT
396 * in which BCM_MAX_DEVS_PER_LINE_CARD macro need to be redefined as 1 incase of
397 * "rlt-1600g-w" and "rlt-1600x-w", till then this workaround is required.*/
Thiyagarajan Subramani4e62e172021-06-25 17:31:30 +0530398 if (dev == 1 && (MODEL_ID == "rlt-1600g-w" || MODEL_ID == "rlt-1600x-w")) {
Girish Gowdrab0337eb2022-03-25 16:44:21 -0700399 continue;
400 }
Thiyagarajan Subramani4e62e172021-06-25 17:31:30 +0530401
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000402 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
Jason Huangbf45ffb2019-10-30 17:29:02 +0800403 if (err == BCM_ERR_NOT_CONNECTED) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000404 bcmolt_device_key key = {.device_id = dev};
405 bcmolt_device_connect oper;
406 BCMOLT_OPER_INIT(&oper, device, connect, key);
Thiyagarajan Subramani3e8bfd92021-04-26 15:07:14 +0530407
Girish Gowdrab0337eb2022-03-25 16:44:21 -0700408 /* BAL saves current state into dram_tune soc file and when dev_mgmt_daemon restarts
409 * it retains config from soc file. If openolt agent try to connect device without
410 * device reset device initialization fails hence doing device reset here. */
Thiyagarajan Subramani3e8bfd92021-04-26 15:07:14 +0530411 reset_pon_device(dev);
Girish Gowdrab0337eb2022-03-25 16:44:21 -0700412 bcmolt_system_mode sm;
413 #ifdef DYNAMIC_PON_TRX_SUPPORT
414 auto sm_res = ponTrx.get_mac_system_mode(dev, ponTrx.get_sfp_presence_data());
415 if (!sm_res.second) {
416 OPENOLT_LOG(ERROR, openolt_log_id, "could not read mac system mode. dev_id = %d\n", dev);
417 continue;
418 }
419 sm = sm_res.first;
420 #else
421 sm = DEFAULT_MAC_SYSTEM_MODE;
422 #endif
423 BCMOLT_MSG_FIELD_SET (&oper, system_mode, sm);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000424 if (MODEL_ID == "asfvolt16") {
425 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000426 } else if (MODEL_ID == "asgvolt64") {
427 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
428 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
Thiyagarajan Subramani4e62e172021-06-25 17:31:30 +0530429 } else if (MODEL_ID == "rlt-3200g-w" || MODEL_ID == "rlt-1600g-w") {
Thiyagarajan Subramani3e8bfd92021-04-26 15:07:14 +0530430 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_NONE);
431 if(dev == 1) {
432 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
433 }
434 BCMOLT_MSG_FIELD_SET (&oper, ras_ddr_mode, BCMOLT_RAS_DDR_USAGE_MODE_TWO_DDRS);
435 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
Thiyagarajan Subramani4e62e172021-06-25 17:31:30 +0530436 } else if (MODEL_ID == "rlt-1600x-w") {
437 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_NONE);
438 BCMOLT_MSG_FIELD_SET (&oper, ras_ddr_mode, BCMOLT_RAS_DDR_USAGE_MODE_TWO_DDRS);
439 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
Arthur Syu094df162022-04-21 17:50:06 +0800440 } else if (MODEL_ID == "sda3016ss") {
441 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_12_P_5_G);
442 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_TWO_TO_ONE);
443 BCMOLT_MSG_FIELD_SET (&oper, ras_ddr_mode, BCMOLT_RAS_DDR_USAGE_MODE_TWO_DDRS);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000444 }
445 err = bcmolt_oper_submit(dev_id, &oper.hdr);
446 if (err) {
447 failed_enable_device_cnt ++;
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500448 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 +0000449 if (failed_enable_device_cnt == BCM_MAX_DEVS_PER_LINE_CARD) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500450 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 +0000451 return Status(grpc::StatusCode::INTERNAL, "Failed to activate all PON ports");
452 }
453 }
Girish Gowdra72bb4652022-01-18 17:04:30 -0800454 bcmos_usleep(MAC_DEVICE_ACTIVATION_DELAY);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000455 }
456 else {
Thiyagarajan Subramani4e62e172021-06-25 17:31:30 +0530457 OPENOLT_LOG(WARNING, openolt_log_id, "PON device %d already connected\n", dev);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000458 state.activate();
459 }
460 }
461 init_stats();
Shad Ansari627b5782018-08-13 22:49:32 +0000462 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000463 }
Shad Ansariedef2132018-08-10 22:14:50 +0000464
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000465 /* Start CLI */
466 OPENOLT_LOG(INFO, def_log_id, "Starting CLI\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400467 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000468 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400469}
470
471Status Disable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400472 //In the earlier implementation Disabling olt is done by disabling the NNI port associated with that.
473 //In inband scenario instead of using management interface to establish connection with adapter ,NNI interface will be used.
474 //Disabling NNI port on olt disable causes connection loss between adapter and agent.
475 //To overcome this disable is implemented by disabling all the PON ports
476 //associated with the device so as to support both in-band
477 //and out of band scenarios.
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400478
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400479 Status status;
480 int failedCount = 0;
Girish Gowdrae1db2952021-05-04 00:16:54 -0700481 OPENOLT_LOG(INFO, openolt_log_id, "Received disable OLT\n");
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400482 for (int i = 0; i < NumPonIf_(); i++) {
483 status = DisablePonIf_(i);
484 if (!status.ok()) {
485 failedCount+=1;
486 BCM_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", i);
487 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400488 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400489 if (failedCount == 0) {
490 state.deactivate();
Girish Gowdra252f4972020-09-07 21:24:01 -0700491 ::openolt::Indication ind;
492 ::openolt::OltIndication* olt_ind = new ::openolt::OltIndication;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400493 olt_ind->set_oper_state("down");
494 ind.set_allocated_olt_ind(olt_ind);
495 BCM_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
496 oltIndQ.push(ind);
497 return Status::OK;
498 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000499 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400500 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to disable olt ,all the PON ports are still in enabled state");
501 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400502
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400503 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 -0400504}
505
506Status Reenable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400507 Status status;
508 int failedCount = 0;
509 for (int i = 0; i < NumPonIf_(); i++) {
510 status = EnablePonIf_(i);
511 if (!status.ok()) {
512 failedCount+=1;
513 BCM_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", i);
514 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400515 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000516 if (failedCount == 0) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400517 state.activate();
Girish Gowdra252f4972020-09-07 21:24:01 -0700518 ::openolt::Indication ind;
519 ::openolt::OltIndication* olt_ind = new ::openolt::OltIndication;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400520 olt_ind->set_oper_state("up");
521 ind.set_allocated_olt_ind(olt_ind);
522 BCM_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
523 oltIndQ.push(ind);
524 return Status::OK;
525 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000526 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400527 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to re-enable olt ,all the PON ports are still in disabled state");
528 }
529 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 +0000530}
531
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000532inline uint64_t get_flow_status(uint16_t flow_id, uint16_t flow_type, uint16_t data_id) {
533 bcmos_errno err;
534 bcmolt_flow_key flow_key;
535 bcmolt_flow_cfg flow_cfg;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400536
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000537 flow_key.flow_id = flow_id;
538 flow_key.flow_type = (bcmolt_flow_type)flow_type;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400539
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000540 BCMOLT_CFG_INIT(&flow_cfg, flow, flow_key);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400541
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000542 switch (data_id) {
543 case ONU_ID: //onu_id
544 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, onu_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500545 #ifdef TEST_MODE
546 // It is impossible to mock the setting of flow_cfg.data.state because
547 // the actual bcmolt_cfg_get passes the address of flow_cfg.hdr and we cannot
548 // set the flow_cfg.data. So a new stub function is created and address
549 // of flow_cfg is passed. This is one-of case where we need to add test specific
550 // code in production code.
551 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
552 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000553 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500554 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000555 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700556 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get onu_id, err = %s (%d)\n", flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000557 return err;
558 }
559 return flow_cfg.data.onu_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400560 case FLOW_TYPE:
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500561 #ifdef TEST_MODE
562 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
563 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000564 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500565 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000566 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700567 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get flow_type, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000568 return err;
569 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400570 return flow_cfg.key.flow_type;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000571 case SVC_PORT_ID: //svc_port_id
572 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, svc_port_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500573 #ifdef TEST_MODE
574 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
575 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000576 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500577 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000578 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700579 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get svc_port_id, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000580 return err;
581 }
582 return flow_cfg.data.svc_port_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400583 case PRIORITY:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000584 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, priority);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500585 #ifdef TEST_MODE
586 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
587 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000588 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500589 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000590 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700591 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get priority, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000592 return err;
593 }
594 return flow_cfg.data.priority;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400595 case COOKIE: //cookie
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000596 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, cookie);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500597 #ifdef TEST_MODE
598 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
599 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000600 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500601 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000602 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700603 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get cookie, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000604 return err;
605 }
606 return flow_cfg.data.cookie;
607 case INGRESS_INTF_TYPE: //ingress intf_type
608 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500609 #ifdef TEST_MODE
610 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
611 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000612 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500613 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000614 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700615 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get ingress intf_type, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000616 return err;
617 }
618 return flow_cfg.data.ingress_intf.intf_type;
619 case EGRESS_INTF_TYPE: //egress intf_type
620 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500621 #ifdef TEST_MODE
622 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
623 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000624 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500625 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000626 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700627 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress intf_type, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000628 return err;
629 }
630 return flow_cfg.data.egress_intf.intf_type;
631 case INGRESS_INTF_ID: //ingress intf_id
632 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500633 #ifdef TEST_MODE
634 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
635 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000636 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500637 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000638 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700639 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get ingress intf_id, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000640 return err;
641 }
642 return flow_cfg.data.ingress_intf.intf_id;
643 case EGRESS_INTF_ID: //egress intf_id
644 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500645 #ifdef TEST_MODE
646 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
647 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000648 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500649 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000650 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700651 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress intf_id, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000652 return err;
653 }
654 return flow_cfg.data.egress_intf.intf_id;
655 case CLASSIFIER_O_VID:
656 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500657 #ifdef TEST_MODE
658 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
659 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000660 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500661 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000662 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700663 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier o_vid, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000664 return err;
665 }
666 return flow_cfg.data.classifier.o_vid;
667 case CLASSIFIER_O_PBITS:
668 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500669 #ifdef TEST_MODE
670 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
671 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000672 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500673 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000674 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700675 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier o_pbits, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000676 return err;
677 }
678 return flow_cfg.data.classifier.o_pbits;
679 case CLASSIFIER_I_VID:
680 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500681 #ifdef TEST_MODE
682 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
683 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000684 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500685 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000686 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700687 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier i_vid, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000688 return err;
689 }
690 return flow_cfg.data.classifier.i_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400691 case CLASSIFIER_I_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000692 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500693 #ifdef TEST_MODE
694 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
695 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000696 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500697 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000698 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700699 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier i_pbits, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000700 return err;
701 }
702 return flow_cfg.data.classifier.i_pbits;
703 case CLASSIFIER_ETHER_TYPE:
704 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500705 #ifdef TEST_MODE
706 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
707 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000708 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500709 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000710 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700711 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier ether_type, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000712 return err;
713 }
714 return flow_cfg.data.classifier.ether_type;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400715 case CLASSIFIER_IP_PROTO:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000716 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500717 #ifdef TEST_MODE
718 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
719 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000720 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500721 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000722 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700723 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier ip_proto, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000724 return err;
725 }
726 return flow_cfg.data.classifier.ip_proto;
727 case CLASSIFIER_SRC_PORT:
728 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500729 #ifdef TEST_MODE
730 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
731 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000732 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500733 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000734 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700735 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier src_port, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000736 return err;
737 }
738 return flow_cfg.data.classifier.src_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400739 case CLASSIFIER_DST_PORT:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000740 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500741 #ifdef TEST_MODE
742 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
743 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000744 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500745 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000746 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700747 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier dst_port, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000748 return err;
749 }
750 return flow_cfg.data.classifier.dst_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400751 case CLASSIFIER_PKT_TAG_TYPE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000752 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500753 #ifdef TEST_MODE
754 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
755 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000756 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500757 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000758 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700759 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier pkt_tag_type, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000760 return err;
761 }
762 return flow_cfg.data.classifier.pkt_tag_type;
763 case EGRESS_QOS_TYPE:
764 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500765 #ifdef TEST_MODE
766 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
767 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000768 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500769 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000770 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700771 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos type, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000772 return err;
773 }
774 return flow_cfg.data.egress_qos.type;
775 case EGRESS_QOS_QUEUE_ID:
776 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500777 #ifdef TEST_MODE
778 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
779 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000780 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500781 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000782 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700783 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos queue_id, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000784 return err;
785 }
786 switch (flow_cfg.data.egress_qos.type) {
787 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE:
788 return flow_cfg.data.egress_qos.u.fixed_queue.queue_id;
789 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE:
790 return flow_cfg.data.egress_qos.u.tc_to_queue.tc_to_queue_id;
791 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC:
792 return flow_cfg.data.egress_qos.u.pbit_to_tc.tc_to_queue_id;
793 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE:
794 return flow_cfg.data.egress_qos.u.priority_to_queue.tm_q_set_id;
795 case BCMOLT_EGRESS_QOS_TYPE_NONE:
796 default:
797 return -1;
798 }
799 case EGRESS_QOS_TM_SCHED_ID:
800 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500801 #ifdef TEST_MODE
802 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
803 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000804 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500805 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000806 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700807 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos tm_sched_id, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000808 return err;
809 }
810 return flow_cfg.data.egress_qos.tm_sched.id;
811 case ACTION_CMDS_BITMASK:
812 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500813 #ifdef TEST_MODE
814 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
815 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000816 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500817 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000818 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700819 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action cmds_bitmask, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000820 return err;
821 }
822 return flow_cfg.data.action.cmds_bitmask;
823 case ACTION_O_VID:
824 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500825 #ifdef TEST_MODE
826 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
827 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000828 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500829 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000830 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700831 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action o_vid, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000832 return err;
833 }
834 return flow_cfg.data.action.o_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400835 case ACTION_O_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000836 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500837 #ifdef TEST_MODE
838 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
839 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000840 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500841 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000842 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700843 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action o_pbits, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000844 return err;
845 }
846 return flow_cfg.data.action.o_pbits;
847 case ACTION_I_VID:
848 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500849 #ifdef TEST_MODE
850 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
851 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000852 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500853 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000854 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700855 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action i_vid, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000856 return err;
857 }
858 return flow_cfg.data.action.i_vid;
859 case ACTION_I_PBITS:
860 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500861 #ifdef TEST_MODE
862 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
863 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000864 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500865 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000866 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700867 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action i_pbits, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000868 return err;
869 }
870 return flow_cfg.data.action.i_pbits;
871 case STATE:
872 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, state);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500873 #ifdef TEST_MODE
874 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
875 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000876 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500877 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000878 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700879 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get state, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000880 return err;
881 }
882 return flow_cfg.data.state;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000883 case GROUP_ID:
884 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, group_id);
885 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
886 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700887 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get group_id, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000888 return err;
889 }
890 return flow_cfg.data.group_id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000891 default:
892 return BCM_ERR_INTERNAL;
893 }
894
895 return err;
896}
897
898Status EnablePonIf_(uint32_t intf_id) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400899 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000900 bcmolt_pon_interface_cfg interface_obj;
901 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
902 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
903 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530904 bcmolt_status los_status;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000905
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530906 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000907 if (err == BCM_ERR_OK) {
908 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800909 OPENOLT_LOG(WARNING, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000910 return Status::OK;
911 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400912 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000913 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
914 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
915 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
916 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.interval, 5000);
917 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.onu_post_discovery_mode,
Girish Gowdra24297032020-03-23 12:32:37 -0700918 BCMOLT_ONU_POST_DISCOVERY_MODE_NONE);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000919 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.los, true);
920 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.onu_alarms, true);
921 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.tiwi, true);
922 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.ack_timeout, true);
923 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.sfi, true);
924 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.loki, true);
Burak Gurdag5e587792020-05-06 14:58:02 +0000925
926 // On GPON, power level mode is not set to its default value (i.e. 0) as documented in Broadcom documentation.
927 // Instead, it is set to 2 which means -6 dbM attenuation. Therefore, we explicitly set it to the default value below.
Arthur Syu094df162022-04-21 17:50:06 +0800928 std::string intf_technology = intf_technologies[intf_id];
929 if (intf_technology == "GPON") {
Burak Gurdag5e587792020-05-06 14:58:02 +0000930 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.pls_maximum_allocation_size, BCMOLT_PON_POWER_LEVEL_PLS_MAXIMUM_ALLOCATION_SIZE_DEFAULT);
931 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.mode, BCMOLT_PON_POWER_LEVEL_MODE_DEFAULT);
Shivanagouda Malaginahalli05bf9d42024-03-16 13:36:17 +0530932 /* PON gpon itu threshold default values for LOSi, LOFi and LOAMi are
933 configured as 4, 4 and 3 respectively. These values are suppressing
934 onu down indication from BAL.
935 To fix this problem all thresholds for LOSi, LOFi and LOAMi are
936 configured with 14. After this configuration BAL started sending
937 onu down indication.
938 */
939 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.onu_alarms_thresholds.losi, 14);
940 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.onu_alarms_thresholds.lofi, 14);
941 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.onu_alarms_thresholds.loami, 14);
Burak Gurdag5e587792020-05-06 14:58:02 +0000942 }
943
Girish Gowdrab0337eb2022-03-25 16:44:21 -0700944 // TODO: Currently the PON Type is set automatically when the MAC System Mode is set. But it could be explicitely set here again.
945 // The data for the PON type is availabe in the PonTrx object (check trx_data)
946
kesavandc1f2db92020-08-31 15:32:06 +0530947 //Enable AES Encryption
948 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.key_exchange, BCMOLT_CONTROL_STATE_ENABLE);
949 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.authentication, BCMOLT_CONTROL_STATE_ENABLE);
950 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.fail_due_to_authentication_failure, BCMOLT_CONTROL_STATE_ENABLE);
Shivanagouda Malaginahalli05bf9d42024-03-16 13:36:17 +0530951 /* PON LOS wait time is set to 500ms, so that ONU LOS will not be seen
952 before PON LOS during manual fiber pull or fiber cut scenarios.
953 */
954 BCMOLT_MSG_FIELD_SET(&interface_obj, los_wait_timeout, 500);
kesavandc1f2db92020-08-31 15:32:06 +0530955
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000956 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
957 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
958
959 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
960 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500961 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 +0000962 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
963 }
964 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
965 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500966 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 +0000967 return bcm_to_grpc_err(err, "Failed to enable PON interface");
968 }
969 else {
970 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
971 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
972 CreateDefaultSched(intf_id, downstream);
973 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400974 }
975
976 return Status::OK;
977}
978
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500979Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000980 bcmos_errno err;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400981 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000982 bcmolt_device_key dev_key = { };
983 bcmolt_olt_cfg olt_cfg = { };
984 bcmolt_olt_key olt_key = { };
985 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
986 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500987
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000988 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
989 topo.topology_maps.arr = &topo_map[0];
990 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
991 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
992 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400993 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000994 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400995 #ifdef TEST_MODE
996 // It is impossible to mock the setting of olt_cfg.data.bal_state because
997 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
998 // set the olt_cfg.data.topology. So a new stub function is created and address
999 // of olt_cfg is passed. This is one-of case where we need to test add specific
1000 // code in production code.
1001 err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
1002 #else
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001003 err = bcmolt_cfg_get_mult_retry(dev_id, &olt_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001004 #endif
1005 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001006 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 +00001007 return bcm_to_grpc_err(err, "cfg: Failed to query OLT topology");
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001008 }
1009
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001010 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
1011 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001012
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001013 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
1014 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001015 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001016
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001017 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
1018 num_of_nni_ports,
1019 num_of_pon_ports,
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001020 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001021
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001022 uint32_t num_failed_cfg_gets = 0;
Jason Huang09b73ea2020-01-08 17:52:05 +08001023 static std::string openolt_version = firmware_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001024 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
1025 dev_key.device_id = devid;
1026 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
1027 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
1028 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
1029 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001030 err = bcmolt_cfg_get_mult_retry(dev_id, &dev_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001031 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001032 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 +00001033 num_failed_cfg_gets++;
1034 continue;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001035 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001036
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001037 std::string bal_version;
1038 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
1039 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
1040 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
Jason Huang09b73ea2020-01-08 17:52:05 +08001041 firmware_version = "BAL." + bal_version + "__" + openolt_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001042
1043 switch(dev_cfg.data.system_mode) {
1044 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
1045 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
1046 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
1047 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
1048 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
1049 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
1050 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
1051 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
1052 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
1053 case 20: board_technology = MIXED_TECH; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,MIXED_TECH); break;
Arthur Syu094df162022-04-21 17:50:06 +08001054 case 38:
1055 board_technology = "XGS-PON";
1056 FILL_ARRAY2(intf_technologies,devid*16,(devid+1)*16,"XGS-PON");
1057 FILL_ARRAY2(intf_technologies,devid*16+1,(devid+1)*16+1,"GPON");
1058 break;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001059 }
1060
1061 switch(dev_cfg.data.chip_family) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001062 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X: chip_family = "Maple"; break;
1063 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X: chip_family = "Aspen"; break;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001064 }
1065
Jason Huang09b73ea2020-01-08 17:52:05 +08001066 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s, family: %s, board_technology: %s\n",
1067 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 +00001068
1069 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001070 }
1071
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001072 /* 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 +00001073 only the devices that retured success*/
1074 if (num_failed_cfg_gets == BCM_MAX_DEVS_PER_LINE_CARD) {
1075 OPENOLT_LOG(ERROR, openolt_log_id, "device: Query of all the devices failed\n");
1076 return bcm_to_grpc_err(err, "device: All devices failed query");
1077 }
1078
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001079 return Status::OK;
1080}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001081
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001082Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001083 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001084 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
1085 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
1086 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001087
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001088 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001089 if (err == BCM_ERR_OK) {
1090 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001091 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001092 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1093 CreateDefaultSched(intf_id, upstream);
1094 CreateDefaultQueue(intf_id, upstream);
1095 return Status::OK;
1096 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1097 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
1098 return Status::OK;
1099 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001100 }
1101
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001102 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
1103 if (set_state) {
1104 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1105 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1106 } else {
1107 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1108 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1109 }
1110 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
1111 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001112 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err = %s\n",
1113 (set_state)?"enable":"disable", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001114 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
1115 }
1116 else {
1117 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
1118 if (set_state) {
1119 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1120 CreateDefaultSched(intf_id, upstream);
1121 CreateDefaultQueue(intf_id, upstream);
1122 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001123 }
1124
1125 return Status::OK;
1126}
1127
Elia Battiston869a5de2022-02-08 11:40:58 +01001128uint32_t GetNniSpeed_(uint32_t intf_id) {
1129 bcmos_errno err = BCM_ERR_OK;
1130
1131 uint32_t speed;
1132 err = get_nni_interface_speed((bcmolt_interface)intf_id, &speed);
1133 if (err != BCM_ERR_OK) {
1134 OPENOLT_LOG(WARNING, openolt_log_id, "Failed to read speed of NNI interface: %d\n", intf_id);
1135 return 0; //This will cause the adapter to use the default speed value
1136 }
1137
1138 return speed;
1139}
1140
balaji.nagarajan394c7e42025-06-30 18:45:59 +05301141Status DisableOnuSerialNumber_(const ::openolt::InterfaceOnuSerialNumber* request) {
1142 bcmos_errno err = BCM_ERR_OK;
1143 uint32_t intf_id = request->intf_id();
1144
1145 // 1. Parse ONU Serial Number â–’~V~R~@~T assuming 4-byte vendor_id + 4-byte vendor_specific
1146 bcmolt_serial_number itu_serial_number = {};
1147 bcmolt_bin_str_4 itu_serial_number_vendor_id = {};
1148 bcmolt_bin_str_4 itu_serial_number_vendor_specific = {};
1149
1150 // Extract vendor_id and vendor_specific from string
1151 // Example onu_serial_number = "BBSM0001530A" â–’~V~R~F~R "BBSM" + binary(vendor_specific)
1152 memcpy(itu_serial_number_vendor_id.arr, ((request->onu_serial_number()).vendor_id()).c_str(), 4);
1153 memcpy(itu_serial_number_vendor_specific.arr, ((request->onu_serial_number()).vendor_specific()).c_str(), 4);
1154
1155
1156 // 2. Set fields in BAL serial number object
1157 BCMOLT_FIELD_SET(&itu_serial_number, serial_number, vendor_id, itu_serial_number_vendor_id);
1158 BCMOLT_FIELD_SET(&itu_serial_number, serial_number, vendor_specific, itu_serial_number_vendor_specific);
1159
1160 OPENOLT_LOG(INFO, openolt_log_id, "Received disable request for ONU serial number %s with vendor_id: %s, vendor_specific: %s\n",
1161 serial_number_to_str(&itu_serial_number).c_str(),
1162 ((request->onu_serial_number()).vendor_id()).c_str(), ((request->onu_serial_number()).vendor_specific()).c_str());
1163
1164 // 3. Prepare disable_serial_number operation on PON interface
1165 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1166 bcmolt_pon_interface_disable_serial_number pon_interface_disable_sn;
1167 BCMOLT_OPER_INIT(&pon_interface_disable_sn, pon_interface, disable_serial_number, intf_key);
1168
1169 // Set the control (enable/disable) and the serial number to disable
1170 BCMOLT_FIELD_SET(&pon_interface_disable_sn.data, pon_interface_disable_serial_number_data,
1171 control, (bcmolt_disable_serial_number_control)BCMOLT_DISABLE_SERIAL_NUMBER_CONTROL_UNICAST_DISABLE);
1172 BCMOLT_FIELD_SET(&pon_interface_disable_sn.data, pon_interface_disable_serial_number_data,
1173 serial_number, itu_serial_number);
1174
1175 // 4. Submit operation
1176 err = bcmolt_oper_submit(dev_id, &pon_interface_disable_sn.hdr);
1177 if(err != BCM_ERR_OK)
1178 {
1179 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable onu serial number %s on port: %d, bcm_err: %s, err_text: %s\n",serial_number_to_str(&itu_serial_number).c_str(), intf_id,
1180 bcmos_strerror(err), pon_interface_disable_sn.hdr.hdr.err_text);
1181 return bcm_to_grpc_err(err, "Failed to disable onu serialnumber");
1182 }
1183 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled Onu Serial number: %s , interface id %d\n",serial_number_to_str(&itu_serial_number).c_str(),intf_id);
1184 return Status::OK;
1185}
1186
1187Status EnableOnuSerialNumber_(const ::openolt::InterfaceOnuSerialNumber* request) {
1188 bcmos_errno err = BCM_ERR_OK;
1189 uint32_t intf_id = request->intf_id();
1190
1191 // 1. Parse ONU Serial Number â–’~V~R~@~T assuming 4-byte vendor_id + 4-byte vendor_specific
1192 bcmolt_serial_number itu_serial_number = {};
1193 bcmolt_bin_str_4 itu_serial_number_vendor_id = {};
1194 bcmolt_bin_str_4 itu_serial_number_vendor_specific = {};
1195
1196 // Extract vendor_id and vendor_specific from string
1197 // Example onu_serial_number = "BBSM0001530A" â–’~V~R~F~R "BBSM" + binary(vendor_specific)
1198 memcpy(itu_serial_number_vendor_id.arr, ((request->onu_serial_number()).vendor_id()).c_str(), 4);
1199 memcpy(itu_serial_number_vendor_specific.arr, ((request->onu_serial_number()).vendor_specific()).c_str(), 4);
1200
1201 // 2. Set fields in BAL serial number object
1202 BCMOLT_FIELD_SET(&itu_serial_number, serial_number, vendor_id, itu_serial_number_vendor_id);
1203 BCMOLT_FIELD_SET(&itu_serial_number, serial_number, vendor_specific, itu_serial_number_vendor_specific);
1204
1205 OPENOLT_LOG(INFO, openolt_log_id, "Received enable request for ONU serial number %s with vendor_id: %s, vendor_specific: %s\n",
1206 serial_number_to_str(&itu_serial_number).c_str(),
1207 ((request->onu_serial_number()).vendor_id()).c_str(), ((request->onu_serial_number()).vendor_specific()).c_str());
1208 // 3. Prepare disable_serial_number operation on PON interface
1209 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1210 bcmolt_pon_interface_disable_serial_number pon_interface_disable_sn;
1211 BCMOLT_OPER_INIT(&pon_interface_disable_sn, pon_interface, disable_serial_number, intf_key);
1212
1213 // Set the control (enable/disable) and the serial number to disable
1214 BCMOLT_FIELD_SET(&pon_interface_disable_sn.data, pon_interface_disable_serial_number_data,
1215 control, (bcmolt_disable_serial_number_control)BCMOLT_DISABLE_SERIAL_NUMBER_CONTROL_UNICAST_ENABLE);
1216 BCMOLT_FIELD_SET(&pon_interface_disable_sn.data, pon_interface_disable_serial_number_data,
1217 serial_number, itu_serial_number);
1218
1219 // 4. Submit operation
1220 err = bcmolt_oper_submit(dev_id, &pon_interface_disable_sn.hdr);
1221 if(err != BCM_ERR_OK)
1222 {
1223 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to enable onu serial number %s on port: %d, bcm_err: %s, err_text: %s\n",serial_number_to_str(&itu_serial_number).c_str(), intf_id,
1224 bcmos_strerror(err), pon_interface_disable_sn.hdr.hdr.err_text);
1225 return bcm_to_grpc_err(err, "Failed to enable onu serialnumber");
1226 }
1227 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled Onu Serial number: %s , interface id %d\n",serial_number_to_str(&itu_serial_number).c_str(),intf_id);
1228 return Status::OK;
1229}
1230
1231Status DisableOnu_(const ::openolt::InterfaceOnuSerialNumberOnuId* request) {
1232 bcmos_errno err = BCM_ERR_OK;
1233 uint32_t intf_id = (request->intf_id_serial_num()).intf_id();
1234 uint32_t onu_id = request->onu_id();
1235
1236 // 1. Parse ONU Serial Number â–’~V~R~@~T assuming 4-byte vendor_id + 4-byte vendor_specific
1237 bcmolt_serial_number itu_serial_number = {};
1238 bcmolt_bin_str_4 itu_serial_number_vendor_id = {};
1239 bcmolt_bin_str_4 itu_serial_number_vendor_specific = {};
1240
1241 // Extract vendor_id and vendor_specific from string
1242 // Example onu_serial_number = "BBSM0001530A" â–’~V~R~F~R "BBSM" + binary(vendor_specific)
1243 memcpy(itu_serial_number_vendor_id.arr, (((request->intf_id_serial_num()).onu_serial_number()).vendor_id()).c_str(), 4);
1244 memcpy(itu_serial_number_vendor_specific.arr, (((request->intf_id_serial_num()).onu_serial_number()).vendor_specific()).c_str(), 4);
1245
1246 // 2. Set fields in BAL serial number object
1247 BCMOLT_FIELD_SET(&itu_serial_number, serial_number, vendor_id, itu_serial_number_vendor_id);
1248 BCMOLT_FIELD_SET(&itu_serial_number, serial_number, vendor_specific, itu_serial_number_vendor_specific);
1249
1250 bcmolt_onu_set_onu_state onu_oper;
1251 bcmolt_onu_key onu_key;
1252 onu_key.onu_id = onu_id;
1253 onu_key.pon_ni = intf_id;
1254 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
1255 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
1256 onu_state, BCMOLT_ONU_OPERATION_DISABLE);
1257
1258 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1259 if (err != BCM_ERR_OK)
1260 {
1261 OPENOLT_LOG(ERROR, openolt_log_id,"Failed to set onu state to disabled.onu serial number=%s, intf_id=%d, onu_id=%d, bcm_err=%s\n",
1262 serial_number_to_str(&itu_serial_number).c_str(),
1263 intf_id, onu_id, bcmos_strerror(err));
1264 return bcm_to_grpc_err(err, "Failed to disable onu");
1265 }
1266 OPENOLT_LOG(ERROR, openolt_log_id, "Successfully disabled Onu device with serial number %s ,id: %d , interface id %d\n",serial_number_to_str(&itu_serial_number).c_str(),onu_id,intf_id);
1267 return Status::OK;
1268}
1269
1270Status EnableOnu_(const ::openolt::InterfaceOnuSerialNumberOnuId* request) {
1271 bcmos_errno err = BCM_ERR_OK;
1272 uint32_t intf_id = (request->intf_id_serial_num()).intf_id();
1273 uint32_t onu_id = request->onu_id();
1274
1275 // 1. Parse ONU Serial Number â–’~V~R~@~T assuming 4-byte vendor_id + 4-byte vendor_specific
1276 bcmolt_serial_number itu_serial_number = {};
1277 bcmolt_bin_str_4 itu_serial_number_vendor_id = {};
1278 bcmolt_bin_str_4 itu_serial_number_vendor_specific = {};
1279
1280 // Extract vendor_id and vendor_specific from string
1281 // Example onu_serial_number = "BBSM0001530A" â–’~V~R~F~R "BBSM" + binary(vendor_specific)
1282 memcpy(itu_serial_number_vendor_id.arr, (((request->intf_id_serial_num()).onu_serial_number()).vendor_id()).c_str(), 4);
1283 memcpy(itu_serial_number_vendor_specific.arr, (((request->intf_id_serial_num()).onu_serial_number()).vendor_specific()).c_str(), 4);
1284
1285 // 2. Set fields in BAL serial number object
1286 BCMOLT_FIELD_SET(&itu_serial_number, serial_number, vendor_id, itu_serial_number_vendor_id);
1287 BCMOLT_FIELD_SET(&itu_serial_number, serial_number, vendor_specific, itu_serial_number_vendor_specific);
1288
1289 bcmolt_onu_set_onu_state onu_oper;
1290 bcmolt_onu_key onu_key;
1291 onu_key.onu_id = onu_id;
1292 onu_key.pon_ni = intf_id;
1293
1294 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
1295 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
1296 onu_state, BCMOLT_ONU_OPERATION_ENABLE);
1297
1298 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1299 if (err != BCM_ERR_OK)
1300 {
1301 OPENOLT_LOG(ERROR, openolt_log_id,"Failed to set onu state to enabled. Serial number=%s, intf_id=%d, onu_id=%d, bcm_err=%s\n",
1302 serial_number_to_str(&itu_serial_number).c_str(),
1303 intf_id, onu_id, bcmos_strerror(err));
1304 return bcm_to_grpc_err(err, "Failed to enable onu");
1305 }
1306 OPENOLT_LOG(ERROR, openolt_log_id, "Successfully enabled Onu device with serial number %s, id: %d , interface id %d\n",serial_number_to_str(&itu_serial_number).c_str(),onu_id,intf_id);
1307 return Status::OK;
1308}
1309
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001310Status DisablePonIf_(uint32_t intf_id) {
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001311 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001312 bcmolt_pon_interface_cfg interface_obj;
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001313 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1314 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001315
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001316 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
Girish Gowdrae1db2952021-05-04 00:16:54 -07001317 BCMOLT_MSG_FIELD_GET(&interface_obj, state);
1318
1319 err = bcmolt_cfg_get(dev_id, &interface_obj.hdr);
1320 if (err != BCM_ERR_OK) {
1321 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch pon port status, PON interface %d, err %d err_text=%s \n", intf_id, err, interface_obj.hdr.hdr.err_text);
1322 return bcm_to_grpc_err(err, "Failed to fetch pon port state");
1323 }
1324 if (interface_obj.data.state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1325 OPENOLT_LOG(INFO, openolt_log_id, "PON Interface already inactive, PON interface %d\n", intf_id);
1326 return Status::OK;
1327 }
1328
1329 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001330 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1331 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_DISABLE);
1332
1333 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1334 if (err != BCM_ERR_OK) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07001335 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable discovery of onu, PON interface %d, err = %s (%d(\n", intf_id, interface_obj.hdr.hdr.err_text, err);
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001336 return bcm_to_grpc_err(err, "Failed to disable discovery of onu");
1337 }
1338
1339 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1340 operation, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1341
1342 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1343 if (err != BCM_ERR_OK) {
1344 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 -04001345 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001346 }
1347
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001348 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled PON interface: %d\n", intf_id);
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001349 return Status::OK;
1350}
1351
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001352Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
kesavandc1f2db92020-08-31 15:32:06 +05301353 const char *vendor_id, const char *vendor_specific, uint32_t pir, bool omcc_encryption_mode) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001354 bcmos_errno err = BCM_ERR_OK;
1355 bcmolt_onu_cfg onu_cfg;
1356 bcmolt_onu_key onu_key;
Shivanagouda Malaginahallie707d612023-08-22 10:40:25 +00001357 bcmolt_serial_number serial_number = {}; /**< ONU serial number */
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001358 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001359
Girish Gowdra24297032020-03-23 12:32:37 -07001360 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1361 bcmolt_onu_state onu_state;
1362
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001363 onu_key.onu_id = onu_id;
1364 onu_key.pon_ni = intf_id;
1365 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1366 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Girish Gowdra24297032020-03-23 12:32:37 -07001367#ifdef TEST_MODE
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001368 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1369 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1370 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1371 // of onu_cfg is passed. This is one-of case where we need to add test specific
1372 // code in production code.
1373 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Girish Gowdra24297032020-03-23 12:32:37 -07001374#else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001375 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Girish Gowdra24297032020-03-23 12:32:37 -07001376#endif
1377 OPENOLT_LOG(INFO, openolt_log_id, "Activate ONU : old state = %d, current state = %d\n",
1378 onu_cfg.data.onu_old_state, onu_cfg.data.onu_state);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001379 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001380 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) {
1381 OPENOLT_LOG(INFO, openolt_log_id, "ONU is already in ACTIVE state, \
1382not processing this request for pon_intf=%d onu_id=%d\n", intf_id, onu_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001383 return Status::OK;
Girish Gowdra24297032020-03-23 12:32:37 -07001384 } else if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_NOT_CONFIGURED &&
1385 onu_cfg.data.onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1386 // We need the ONU to be in NOT_CONFIGURED or INACTIVE state to further process the request
1387 OPENOLT_LOG(ERROR, openolt_log_id, "ONU in an invalid state to process the request, \
1388state=%d pon_intf=%d onu_id=%d\n", onu_cfg.data.onu_state, intf_id, onu_id);
1389 return bcm_to_grpc_err(err, "Failed to activate ONU, invalid ONU state");
1390 }
1391 } else {
1392 // This should never happen. BAL GET should succeed for non-existant ONUs too. The state of such ONUs will be NOT_CONFIGURED
1393 OPENOLT_LOG(ERROR, openolt_log_id, "ONU state query failed pon_intf=%d onu_id=%d\n", intf_id, onu_id);
1394 return bcm_to_grpc_err(err, "onu get failed");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001395 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001396
Girish Gowdra24297032020-03-23 12:32:37 -07001397 // If the ONU is not configured at all we need to first configure it
1398 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_NOT_CONFIGURED) {
1399 OPENOLT_LOG(INFO, openolt_log_id, "Configuring ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001400vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Girish Gowdra24297032020-03-23 12:32:37 -07001401 vendor_specific_to_str(vendor_specific).c_str(), pir);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001402
Girish Gowdra24297032020-03-23 12:32:37 -07001403 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1404 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
Shivanagouda Malaginahallie707d612023-08-22 10:40:25 +00001405
Girish Gowdra24297032020-03-23 12:32:37 -07001406 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1407 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1408 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1409 /*set burst and data profiles to fec disabled*/
Arthur Syu094df162022-04-21 17:50:06 +08001410 std::string intf_technology = intf_technologies[intf_id];
1411 if (intf_technology == "XGS-PON") {
Girish Gowdra24297032020-03-23 12:32:37 -07001412 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1413 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
Arthur Syu094df162022-04-21 17:50:06 +08001414 } else if (intf_technology == "GPON") {
Girish Gowdra24297032020-03-23 12:32:37 -07001415 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1416 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1417 }
1418 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1419 if (err != BCM_ERR_OK) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07001420 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to configure ONU %d on PON %d, err = %s (%d)\n", onu_id, intf_id, onu_cfg.hdr.hdr.err_text, err);
Girish Gowdra24297032020-03-23 12:32:37 -07001421 return bcm_to_grpc_err(err, "Failed to configure ONU");
1422 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001423 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001424
Burak Gurdaga0523592021-02-24 15:17:47 +00001425// TODO: MOVE THIS TO A NEW METHOD
kesavandc1f2db92020-08-31 15:32:06 +05301426 if (omcc_encryption_mode == true) {
1427 // set the encryption mode for omci port id
1428 bcmolt_itupon_gem_cfg gem_cfg;
1429 bcmolt_itupon_gem_key key = {};
1430 bcmolt_gem_port_configuration configuration = {};
1431 key.pon_ni = intf_id;
1432 key.gem_port_id = onu_id;
1433 bcmolt_control_state encryption_mode;
1434 encryption_mode = BCMOLT_CONTROL_STATE_ENABLE;
1435 BCMOLT_CFG_INIT(&gem_cfg, itupon_gem, key);
1436 BCMOLT_FIELD_SET(&gem_cfg.data, itupon_gem_cfg_data, encryption_mode, encryption_mode);
1437 err = bcmolt_cfg_set(dev_id, &gem_cfg.hdr);
1438 if(err != BCM_ERR_OK) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07001439 OPENOLT_LOG(ERROR, openolt_log_id, "failed to configure omci gem_port encryption mode = %d, err = %s (%d)\n", onu_id, gem_cfg.hdr.hdr.err_text, err);
kesavandc1f2db92020-08-31 15:32:06 +05301440 return bcm_to_grpc_err(err, "Access_Control set ITU PON OMCI Gem port failed");
1441 }
1442 }
Girish Gowdra24297032020-03-23 12:32:37 -07001443 // Now that the ONU is configured, move the ONU to ACTIVE state
1444 memset(&onu_cfg, 0, sizeof(bcmolt_onu_cfg));
1445 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1446 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1447 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
1448 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
1449 onu_state, BCMOLT_ONU_OPERATION_ACTIVE);
1450 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001451 if (err != BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001452 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 +00001453 return bcm_to_grpc_err(err, "Failed to activate ONU");
1454 }
Girish Gowdra24297032020-03-23 12:32:37 -07001455 // ONU will eventually get activated after we have submitted the operation request. The adapter will receive an asynchronous
1456 // ONU_ACTIVATION_COMPLETED_INDICATION
1457
1458 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 +00001459
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001460 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001461}
1462
Jonathan Davis70c21812018-07-19 15:32:10 -04001463Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1464 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001465 bcmos_errno err = BCM_ERR_OK;
1466 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1467 bcmolt_onu_cfg onu_cfg;
1468 bcmolt_onu_key onu_key; /**< Object key. */
1469 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001470
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001471 onu_key.onu_id = onu_id;
1472 onu_key.pon_ni = intf_id;
1473 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1474 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1475 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301476 onu_state = onu_cfg.data.onu_state;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001477 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001478 switch (onu_state) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001479 case BCMOLT_ONU_STATE_ACTIVE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001480 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001481 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001482 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1483 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1484 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001485 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 +00001486 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1487 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301488 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 +00001489 break;
1490 }
Girish Gowdra72cbee92021-11-05 15:16:18 -07001491 } else {
1492 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to deactivate ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
1493 return bcm_to_grpc_err(err, "Failed to get onu config");
Jonathan Davis70c21812018-07-19 15:32:10 -04001494 }
1495
1496 return Status::OK;
1497}
1498
1499Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001500 const char *vendor_id, const char *vendor_specific) {
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301501 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301502 bcmolt_onu_state onu_state;
Girish Gowdra72cbee92021-11-05 15:16:18 -07001503 Status st;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001504
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001505 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 -05001506 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1507
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001508 // Need to deactivate before removing it (BAL rules)
Girish Gowdra72cbee92021-11-05 15:16:18 -07001509 st = DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
1510 if (st.error_code() != grpc::StatusCode::OK) {
1511 return st;
1512 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301513
Girish Gowdra72cbee92021-11-05 15:16:18 -07001514 err = get_onu_state((bcmolt_interface)intf_id, onu_id, &onu_state);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301515 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001516 if (onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1517 OPENOLT_LOG(INFO, openolt_log_id, "waiting for onu deactivate complete response: intf_id=%d, onu_id=%d\n",
1518 intf_id, onu_id);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301519 err = wait_for_onu_deactivate_complete(intf_id, onu_id);
1520 if (err) {
1521 OPENOLT_LOG(ERROR, openolt_log_id, "failed to delete onu intf_id %d, onu_id %d\n",
1522 intf_id, onu_id);
1523 return bcm_to_grpc_err(err, "Failed to delete ONU");
1524 }
1525 }
Girish Gowdra24297032020-03-23 12:32:37 -07001526 else {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301527 OPENOLT_LOG(INFO, openolt_log_id, "Onu is Inactive, onu_id: %d, not waiting for onu deactivate complete response\n",
1528 intf_id);
1529 }
1530 }
1531 else {
1532 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch Onu status, onu_id = %d, intf_id = %d, err = %s\n",
1533 onu_id, intf_id, bcmos_strerror(err));
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301534 return bcm_to_grpc_err(err, "Failed to delete ONU");
1535 }
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001536
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001537 bcmolt_onu_cfg cfg_obj;
1538 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001539
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001540 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 -04001541 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001542
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001543 key.onu_id = onu_id;
1544 key.pon_ni = intf_id;
1545 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001546
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301547 err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001548 if (err != BCM_ERR_OK)
1549 {
Girish Gowdra72cbee92021-11-05 15:16:18 -07001550 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to clear information for BAL onu_id %d, Interface ID %d, err = %s (%d)\n", onu_id, intf_id, cfg_obj.hdr.hdr.err_text, err);
Jonathan Davis70c21812018-07-19 15:32:10 -04001551 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1552 }
1553
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301554 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 +00001555 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001556}
1557
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001558#define MAX_CHAR_LENGTH 20
1559#define MAX_OMCI_MSG_LENGTH 44
1560Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001561 bcmolt_bin_str buf = {};
1562 bcmolt_onu_cpu_packets omci_cpu_packets;
1563 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001564
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001565 key.pon_ni = intf_id;
1566 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001567
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001568 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1569 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1570 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001571
1572 // ???
1573 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1574 buf.len = MAX_OMCI_MSG_LENGTH;
1575 } else {
1576 buf.len = pkt.size()/2;
1577 }
1578
1579 /* Send the OMCI packet using the BAL remote proxy API */
1580 uint16_t idx1 = 0;
1581 uint16_t idx2 = 0;
1582 uint8_t arraySend[buf.len];
1583 char str1[MAX_CHAR_LENGTH];
1584 char str2[MAX_CHAR_LENGTH];
1585 memset(&arraySend, 0, buf.len);
1586
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001587 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1588 sprintf(str1,"%c", pkt[idx1]);
1589 sprintf(str2,"%c", pkt[++idx1]);
1590 strcat(str1,str2);
1591 arraySend[idx2] = strtol(str1, NULL, 16);
1592 }
1593
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001594 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1595 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001596
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001597 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1598 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1599 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001600
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001601 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001602 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001603 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 +00001604 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001605 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001606 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 -05001607 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001608 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001609 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001610
1611 return Status::OK;
1612}
1613
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001614Status 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 +00001615 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1616 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1617 bcmolt_bin_str buf = {};
1618 bcmolt_gem_port_id gem_port_id_array[1];
1619 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001620
Craig Lutgen967a1d02018-11-27 10:41:51 -06001621 if (port_no > 0) {
1622 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001623 if (gemport_id == 0) {
1624 bcmos_fastlock_lock(&data_lock);
1625 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1626 // Pick any flow that is mapped with the same port_no.
1627 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1628 if (it != port_to_flows.end() && !it->second.empty()) {
1629 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1630 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1631 if (fit != flowid_to_gemport.end()) {
1632 found = true;
1633 gemport_id = fit->second;
1634 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001635 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001636 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001637
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001638 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001639 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 -08001640 onu_id, port_no, intf_id);
1641 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1642 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001643 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 -08001644 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001645 }
1646
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001647 gem_port_id_array[0] = gemport_id;
1648 gem_port_list.len = 1;
1649 gem_port_list.arr = gem_port_id_array;
1650 buf.len = pkt.size();
1651 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1652 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1653
1654 /* init the API struct */
1655 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1656 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1657 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1658 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1659 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1660
1661 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1662 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1663
1664 /* call API */
1665 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001666 }
1667 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001668 //TODO: Port No is 0, it is coming sender requirement.
1669 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1670 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001671 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001672 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001673
1674 return Status::OK;
1675}
1676
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001677Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001678 bcmolt_flow_key key = {}; /* declare key */
1679 bcmolt_bin_str buffer = {};
1680 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001681
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001682 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
Girish Gowdra252f4972020-09-07 21:24:01 -07001683 bcmolt_flow_id flow_id = INVALID_FLOW_ID;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001684
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001685 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1686 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1687 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1688 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1689 key.flow_id = flow_id;
1690 else {
Jason Huang09b73ea2020-01-08 17:52:05 +08001691 if (flow_id_counters) {
1692 std::map<flow_pair, int>::iterator it;
1693 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1694 int flow_index = it->first.first;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001695 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1696 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1697 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1698 key.flow_id = flow_index;
1699 break;
1700 }
1701 }
1702 }
1703 else {
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001704 OPENOLT_LOG(ERROR, openolt_log_id, "no flow id found for uplink packetout\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001705 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1706 }
1707 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001708
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001709 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001710
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001711 /* Initialize the API struct. */
1712 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001713
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001714 buffer.len = pkt.size();
1715 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1716 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1717 if (buffer.arr == NULL) {
1718 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1719 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1720 }
1721 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1722
1723 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1724 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001725 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 -05001726 return bcm_to_grpc_err(BCM_ERR_SYSCALL_ERR, "Error sending packets via nni port");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001727 } else {
1728 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1729 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001730
1731 return Status::OK;
1732}
Girish Gowdra252f4972020-09-07 21:24:01 -07001733
Burak Gurdaga0523592021-02-24 15:17:47 +00001734bool get_aes_flag_for_gem_port(const google::protobuf::Map<unsigned int, bool> &gemport_to_aes, uint32_t gemport_id) {
1735 bool aes_flag = false;
1736 for (google::protobuf::Map<unsigned int, bool>::const_iterator it=gemport_to_aes.begin(); it!=gemport_to_aes.end(); it++) {
1737 if (it->first == gemport_id) {
1738 aes_flag = it->second;
1739 break;
1740 }
1741 }
1742 return aes_flag;
1743}
1744
Girish Gowdra252f4972020-09-07 21:24:01 -07001745Status FlowAddWrapper_(const ::openolt::Flow* request) {
1746
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001747 Status st = Status::OK;
Girish Gowdra252f4972020-09-07 21:24:01 -07001748 int32_t access_intf_id = request->access_intf_id();
1749 int32_t onu_id = request->onu_id();
1750 int32_t uni_id = request->uni_id();
1751 uint32_t port_no = request->port_no();
1752 uint64_t voltha_flow_id = request->flow_id();
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001753 uint64_t symmetric_voltha_flow_id = 0;
Girish Gowdra252f4972020-09-07 21:24:01 -07001754 const std::string flow_type = request->flow_type();
1755 int32_t alloc_id = request->alloc_id();
1756 int32_t network_intf_id = request->network_intf_id();
1757 int32_t gemport_id = request->gemport_id();
1758 const ::openolt::Classifier& classifier = request->classifier();
1759 const ::openolt::Action& action = request->action();
1760 int32_t priority = request->priority();
1761 uint64_t cookie = request->cookie();
1762 int32_t group_id = request->group_id();
1763 uint32_t tech_profile_id = request->tech_profile_id();
1764 bool replicate_flow = request->replicate_flow();
1765 const google::protobuf::Map<unsigned int, unsigned int> &pbit_to_gemport = request->pbit_to_gemport();
Burak Gurdaga0523592021-02-24 15:17:47 +00001766 const google::protobuf::Map<unsigned int, bool> &gemport_to_aes = request->gemport_to_aes();
Girish Gowdra252f4972020-09-07 21:24:01 -07001767 uint16_t flow_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001768 bool enable_encryption;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001769 // When following conditions are ALL met, it qualifies as datapath flow.
1770 // 1. valid access_intf_id, onu_id, uni_id
1771 // 2. Valid tech_profile_id
1772 // 3. flow_type that is not MULTICAST
1773 // 4. Not a trap-to-host flow.
1774 bool datapathFlow = access_intf_id >= 0 && onu_id >= 0 && uni_id >= 0 && tech_profile_id > 0
1775 && flow_type != multicast && !action.cmd().trap_to_host();
1776
1777 if (datapathFlow) {
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08001778 const std::string inverse_flow_type = flow_type == upstream? downstream : upstream;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001779 symmetric_datapath_flow_id_map_key key(access_intf_id, onu_id, uni_id, tech_profile_id, inverse_flow_type);
1780 // Find the onu-uni mapping for the pon-gem key
1781 bcmos_fastlock_lock(&symmetric_datapath_flow_id_lock);
1782 auto it = symmetric_datapath_flow_id_map.find(key);
1783 bcmos_fastlock_unlock(&symmetric_datapath_flow_id_lock, 0);
1784 if (it != symmetric_datapath_flow_id_map.end()) {
1785 symmetric_voltha_flow_id = it->second;
1786 }
1787 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001788
1789 // The intf_id variable defaults to access(PON) interface ID.
1790 // For trap-from-nni flow where access interface ID is not valid , change it to NNI interface ID
1791 // This intf_id identifies the pool from which we get the flow_id
1792 uint32_t intf_id = access_intf_id;
1793 if (onu_id < 1) {
1794 onu_id = 1;
1795 }
1796 if (access_intf_id < 0) {
1797 intf_id = network_intf_id;
1798 }
1799
Sridhar Ravindra57d7eb92025-06-04 13:39:43 +05301800 OPENOLT_LOG(INFO, openolt_log_id, "received flow add. voltha_flow_id=%lu, symmetric_voltha_flow_id=%lu, network_intf_id=%d, replication=%d\n", voltha_flow_id, symmetric_voltha_flow_id, network_intf_id, replicate_flow);
Girish Gowdra252f4972020-09-07 21:24:01 -07001801 // This is the case of voltha_flow_id (not symmetric_voltha_flow_id)
1802 if (is_voltha_flow_installed(voltha_flow_id)) {
1803 OPENOLT_LOG(INFO, openolt_log_id, "voltha_flow_id=%lu, already installed\n", voltha_flow_id);
1804 return ::Status(grpc::StatusCode::ALREADY_EXISTS, "voltha-flow-already-installed");
1805 }
1806
Girish Gowdra252f4972020-09-07 21:24:01 -07001807 // This is the case of symmetric_voltha_flow_id
1808 // If symmetric_voltha_flow_id is available and valid in the Flow message,
1809 // check if it is installed, and use the corresponding device_flow_id
1810 if (symmetric_voltha_flow_id > 0 && is_voltha_flow_installed(symmetric_voltha_flow_id)) { // symmetric flow found
1811 OPENOLT_LOG(INFO, openolt_log_id, "symmetric flow and the symmetric flow is installed\n");
1812 const device_flow_params *dev_fl_symm_params;
1813 dev_fl_symm_params = get_device_flow_params(symmetric_voltha_flow_id);
1814 if (dev_fl_symm_params == NULL) {
1815 OPENOLT_LOG(ERROR, openolt_log_id, "symmetric flow device params not found symm-voltha-flow=%lu voltha-flow=%lu\n", symmetric_voltha_flow_id, voltha_flow_id)
1816 return ::Status(grpc::StatusCode::INTERNAL, "symmetric-flow-details-not-found");
1817 }
1818
1819 if (!replicate_flow) { // No flow replication
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001820 flow_id = dev_fl_symm_params[0].flow_id;
1821 gemport_id = dev_fl_symm_params[0].gemport_id; // overwrite the gemport with symmetric flow gemport
1822 // Should be same as what is coming in this request.
1823 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
1824 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1825 cl.set_o_pbits(dev_fl_symm_params[0].pbit);
1826 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1827 flow_type, alloc_id, network_intf_id, gemport_id, cl,
1828 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
1829 if (st.error_code() != grpc::StatusCode::OK && st.error_code() != grpc::StatusCode::ALREADY_EXISTS) {
1830 OPENOLT_LOG(ERROR, openolt_log_id, "failed to install device flow=%u for voltha flow=%lu", flow_id, voltha_flow_id);
Girish Gowdra72cbee92021-11-05 15:16:18 -07001831 free_flow_id(flow_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001832 return st;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001833 }
1834
1835 device_flow dev_fl;
1836 dev_fl.is_flow_replicated = false;
1837 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1838 dev_fl.voltha_flow_id = voltha_flow_id;
Girish Gowdra72bb4652022-01-18 17:04:30 -08001839 dev_fl.flow_type = flow_type;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001840 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params));
1841 // update voltha flow to cache
1842 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
Girish Gowdra252f4972020-09-07 21:24:01 -07001843 } else { // Flow to be replicated
1844 OPENOLT_LOG(INFO, openolt_log_id,"symmetric flow and replication is needed\n");
Girish Gowdra52997cc2022-06-02 20:58:50 -07001845 if (pbit_to_gemport.size() > NUMBER_OF_PBITS) {
1846 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pbit-to-gemport map size=%lu", pbit_to_gemport.size())
1847 return ::Status(grpc::StatusCode::OUT_OF_RANGE, "pbit-to-gemport-map-len-invalid-for-flow-replication");
1848 }
1849 for (uint8_t i=0; i<pbit_to_gemport.size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07001850 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1851 flow_id = dev_fl_symm_params[i].flow_id;
1852 gemport_id = dev_fl_symm_params[i].gemport_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001853 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001854 cl.set_o_pbits(dev_fl_symm_params[i].pbit);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001855 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdrade65ab42020-12-17 23:08:43 -08001856 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001857 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001858 if (st.error_code() != grpc::StatusCode::OK && st.error_code() != grpc::StatusCode::ALREADY_EXISTS) {
1859 OPENOLT_LOG(ERROR, openolt_log_id, "failed to install device flow=%u for voltha flow=%lu. Undoing any device flows installed.", flow_id, voltha_flow_id);
1860 // On failure remove any successfully replicated flows installed so far for the voltha_flow_id
1861 if (i > 0) {
1862 for (int8_t j = i-1; j >= 0; j--) {
1863 flow_id = dev_fl_symm_params[j].flow_id;
1864 FlowRemove_(flow_id, flow_type);
1865 }
1866 }
Girish Gowdra72cbee92021-11-05 15:16:18 -07001867 // Note: We should not free the flow_ids here because the symmetric flow is already using that flow id.
1868 // A call from voltha adapter should invoke a flow remove and then the flow ids would be freed in the process in this particular case
Girish Gowdra252f4972020-09-07 21:24:01 -07001869 return st;
1870 }
1871 }
1872 device_flow dev_fl;
1873 dev_fl.is_flow_replicated = true;
1874 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1875 dev_fl.voltha_flow_id = voltha_flow_id;
Girish Gowdra52997cc2022-06-02 20:58:50 -07001876 dev_fl.total_replicated_flows = pbit_to_gemport.size();
Girish Gowdra72bb4652022-01-18 17:04:30 -08001877 dev_fl.flow_type = flow_type;
Girish Gowdra52997cc2022-06-02 20:58:50 -07001878 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params)*dev_fl.total_replicated_flows);
Girish Gowdra252f4972020-09-07 21:24:01 -07001879 // update voltha flow to cache
1880 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1881 }
1882 } else { // No symmetric flow found
1883 if (!replicate_flow) { // No flow replication
1884 OPENOLT_LOG(INFO, openolt_log_id, "not a symmetric flow and replication is not needed\n");
1885 flow_id = get_flow_id();
1886 if (flow_id == INVALID_FLOW_ID) {
1887 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocated flow id for voltha-flow-id=%lu\n", voltha_flow_id);
1888 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1889 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001890 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001891 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001892 flow_type, alloc_id, network_intf_id, gemport_id, classifier,
Burak Gurdaga0523592021-02-24 15:17:47 +00001893 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001894 if (st.error_code() == grpc::StatusCode::OK) {
1895 device_flow dev_fl;
1896 dev_fl.is_flow_replicated = false;
1897 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // Invalid
1898 dev_fl.voltha_flow_id = voltha_flow_id;
Girish Gowdra72bb4652022-01-18 17:04:30 -08001899 dev_fl.flow_type = flow_type;
Girish Gowdra252f4972020-09-07 21:24:01 -07001900 dev_fl.params[0].flow_id = flow_id;
1901 dev_fl.params[0].gemport_id = gemport_id;
1902 dev_fl.params[0].pbit = classifier.o_pbits();
1903 // update voltha flow to cache
1904 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1905 } else {
1906 // Free the flow id on failure
1907 free_flow_id(flow_id);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001908 return st;
Girish Gowdra252f4972020-09-07 21:24:01 -07001909 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001910 } else { // Flow to be replicated
1911 OPENOLT_LOG(INFO, openolt_log_id,"not a symmetric flow and replication is needed\n");
Girish Gowdra52997cc2022-06-02 20:58:50 -07001912 if (pbit_to_gemport.size() > NUMBER_OF_PBITS) {
Girish Gowdra252f4972020-09-07 21:24:01 -07001913 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pbit-to-gemport map size=%lu", pbit_to_gemport.size())
1914 return ::Status(grpc::StatusCode::OUT_OF_RANGE, "pbit-to-gemport-map-len-invalid-for-flow-replication");
1915 }
Girish Gowdra52997cc2022-06-02 20:58:50 -07001916 uint16_t flow_ids[MAX_NUMBER_OF_REPLICATED_FLOWS];
Girish Gowdra252f4972020-09-07 21:24:01 -07001917 device_flow dev_fl;
Girish Gowdra52997cc2022-06-02 20:58:50 -07001918 if (get_flow_ids(pbit_to_gemport.size(), flow_ids)) {
Girish Gowdra252f4972020-09-07 21:24:01 -07001919 uint8_t cnt = 0;
1920 dev_fl.is_flow_replicated = true;
1921 dev_fl.voltha_flow_id = voltha_flow_id;
1922 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // invalid
Girish Gowdra52997cc2022-06-02 20:58:50 -07001923 dev_fl.total_replicated_flows = pbit_to_gemport.size();
Girish Gowdra72bb4652022-01-18 17:04:30 -08001924 dev_fl.flow_type = flow_type;
Girish Gowdra252f4972020-09-07 21:24:01 -07001925 for (google::protobuf::Map<unsigned int, unsigned int>::const_iterator it=pbit_to_gemport.begin(); it!=pbit_to_gemport.end(); it++) {
1926 dev_fl.params[cnt].flow_id = flow_ids[cnt];
1927 dev_fl.params[cnt].pbit = it->first;
1928 dev_fl.params[cnt].gemport_id = it->second;
1929
1930 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1931 flow_id = dev_fl.params[cnt].flow_id;
1932 gemport_id = dev_fl.params[cnt].gemport_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001933 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001934 cl.set_o_pbits(dev_fl.params[cnt].pbit);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001935 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001936 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001937 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001938 if (st.error_code() != grpc::StatusCode::OK) {
1939 OPENOLT_LOG(ERROR, openolt_log_id, "failed to install device flow=%u for voltha flow=%lu. Undoing any device flows installed.", flow_id, voltha_flow_id);
1940 // Remove any successfully replicated flows installed so far for the voltha_flow_id
1941 if (cnt > 0) {
1942 for (int8_t j = cnt-1; j >= 0; j--) {
1943 flow_id = dev_fl.params[j].flow_id;
1944 FlowRemove_(flow_id, flow_type);
1945 }
1946 }
1947 // Free up all the flow IDs on failure
Girish Gowdra52997cc2022-06-02 20:58:50 -07001948 free_flow_ids(pbit_to_gemport.size(), flow_ids);
Girish Gowdra252f4972020-09-07 21:24:01 -07001949 return st;
1950 }
1951 cnt++;
1952 }
1953 // On successful flow replication update voltha-flow-id to device-flow map to cache
1954 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1955 } else {
1956 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocate flow ids for replication voltha-flow-id=%lu\n", voltha_flow_id);
1957 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1958 }
1959 }
1960 }
1961
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001962 if (datapathFlow) {
1963 // Create the pon-gem to onu-uni mapping
1964 symmetric_datapath_flow_id_map_key key(access_intf_id, onu_id, uni_id, tech_profile_id, flow_type);
1965 bcmos_fastlock_lock(&symmetric_datapath_flow_id_lock);
1966 symmetric_datapath_flow_id_map[key] = voltha_flow_id;
1967 bcmos_fastlock_unlock(&symmetric_datapath_flow_id_lock, 0);
1968 }
1969
1970 return st;
Girish Gowdra252f4972020-09-07 21:24:01 -07001971}
1972
1973
Craig Lutgen967a1d02018-11-27 10:41:51 -06001974Status 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 +00001975 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001976 int32_t alloc_id, int32_t network_intf_id,
1977 int32_t gemport_id, const ::openolt::Classifier& classifier,
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001978 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie,
Burak Gurdaga0523592021-02-24 15:17:47 +00001979 int32_t group_id, uint32_t tech_profile_id, bool aes_enabled) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001980 bcmolt_flow_cfg cfg;
1981 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001982 int32_t o_vid = -1;
1983 bool single_tag = false;
1984 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001985 bcmolt_classifier c_val = { };
1986 bcmolt_action a_val = { };
1987 bcmolt_tm_queue_ref tm_val = { };
1988 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05001989 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001990
Jason Huang09b73ea2020-01-08 17:52:05 +08001991 OPENOLT_LOG(INFO, openolt_log_id, "flow add received for flow_id=%u, flow_type=%s\n", flow_id, flow_type.c_str());
1992
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001993 key.flow_id = flow_id;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08001994 if (flow_type == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001995 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08001996 } else if (flow_type == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001997 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08001998 } else if (flow_type == multicast) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001999 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002000 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002001 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04002002 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002003 }
2004
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002005 BCMOLT_CFG_INIT(&cfg, flow, key);
2006 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002007
Jason Huang09b73ea2020-01-08 17:52:05 +08002008 if (action.cmd().trap_to_host()) {
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002009 Status resp = handle_acl_rule_install(onu_id, flow_id, gemport_id, flow_type, access_intf_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07002010 network_intf_id, classifier);
Jason Huang09b73ea2020-01-08 17:52:05 +08002011 return resp;
2012 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002013
2014 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
2015
2016 if (access_intf_id >= 0 && network_intf_id >= 0) {
2017 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
2018 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
2019 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002020 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
2021 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002022 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
2023 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
2024 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
2025 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
2026 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002027 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002028 } else {
2029 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
2030 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002031 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002032
Burak Gurdaga0523592021-02-24 15:17:47 +00002033 if (onu_id >= ONU_ID_START) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002034 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
2035 }
Burak Gurdaga0523592021-02-24 15:17:47 +00002036 if (gemport_id >= GEM_PORT_ID_START) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002037 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
2038 }
Burak Gurdaga0523592021-02-24 15:17:47 +00002039 if (gemport_id >= GEM_PORT_ID_START && port_no != 0) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002040 bcmos_fastlock_lock(&data_lock);
2041 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
2042 port_to_flows[port_no].insert(key.flow_id);
2043 flowid_to_gemport[key.flow_id] = gemport_id;
2044 }
2045 else
2046 {
2047 flowid_to_port[key.flow_id] = port_no;
2048 }
2049 bcmos_fastlock_unlock(&data_lock, 0);
2050 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002051
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002052 if (priority_value >= 0) {
2053 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
2054 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302055
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002056 } else { // MULTICAST FLOW
2057 if (group_id >= 0) {
2058 BCMOLT_MSG_FIELD_SET(&cfg, group_id, group_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002059 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002060 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
2061 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00002062 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002063
2064 {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002065 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002066 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002067 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
2068 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002069 }
2070
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002071 if (classifier.dst_mac().size() > 0) {
2072 bcmos_mac_address d_mac = {};
2073 bcmos_mac_address_init(&d_mac);
2074 memcpy(d_mac.u8, classifier.dst_mac().data(), sizeof(d_mac.u8));
2075 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_mac %02x:%02x:%02x:%02x:%02x:%02x\n", d_mac.u8[0],
2076 d_mac.u8[1], d_mac.u8[2], d_mac.u8[3], d_mac.u8[4], d_mac.u8[5]);
2077 BCMOLT_FIELD_SET(&c_val, classifier, dst_mac, d_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002078 }
2079
Girish Gowdraf83e17a2022-02-16 16:27:00 -08002080 if (classifier.src_mac().size() > 0) {
2081 bcmos_mac_address s_mac = {};
2082 bcmos_mac_address_init(&s_mac);
2083 memcpy(s_mac.u8, classifier.src_mac().data(), sizeof(s_mac.u8));
2084 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_mac %02x:%02x:%02x:%02x:%02x:%02x\n", s_mac.u8[0],
2085 s_mac.u8[1], s_mac.u8[2], s_mac.u8[3], s_mac.u8[4], s_mac.u8[5]);
2086 BCMOLT_FIELD_SET(&c_val, classifier, src_mac, s_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002087 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002088
2089 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002090 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
2091 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002092 }
2093
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002094 if (classifier.dst_ip()) {
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08002095 bcmos_ipv4_address d_ip = {};
2096 bcmos_ipv4_address_init(&d_ip);
2097 d_ip.u32 = classifier.dst_ip();
2098 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_ip %04x\n", d_ip.u32);
2099 BCMOLT_FIELD_SET(&c_val, classifier, dst_ip, d_ip);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002100 }
2101
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08002102 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002103 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002104 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002105 }
2106 */
2107
2108 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002109 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
2110 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002111 }
2112
2113 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002114 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
2115 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002116 }
2117
2118 if (!classifier.pkt_tag_type().empty()) {
Jason Huang09b73ea2020-01-08 17:52:05 +08002119 if (classifier.o_vid()) {
2120 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
2121 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
2122 }
2123
2124 if (classifier.i_vid()) {
2125 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
2126 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
2127 }
2128
2129 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
2130 if (classifier.pkt_tag_type().compare("untagged") == 0) {
2131 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
2132 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
2133 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
2134 single_tag = true;
2135
2136 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05302137 // OpenOlt adapter will send 0xFF in case of no pbit classification
2138 // If it is any other value (0 to 7), it is for outer pbit classification.
2139 // OpenFlow protocol does not provide inner pbit classification (in case of double tagged packets),
2140 // and VOLTHA has not used any workaround to solve this problem (for ex: use metadata field).
2141 // Also there exists no use case for i-pbit classification, so we can safely ignore this for now.
2142 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08002143 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302144 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002145 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
2146 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002147
Jason Huang09b73ea2020-01-08 17:52:05 +08002148 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05302149 // Same comments as in case of "single_tag" packets.
2150 // 0xFF means no pbit classification, otherwise a valid PCP (0 to 7).
2151 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08002152 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302153 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002154 }
2155 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002156 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002157 }
2158
Jason Huang09b73ea2020-01-08 17:52:05 +08002159 const ::openolt::ActionCmd& cmd = action.cmd();
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002160
Jason Huang09b73ea2020-01-08 17:52:05 +08002161 if (cmd.add_outer_tag()) {
2162 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
2163 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002164 }
2165
Jason Huang09b73ea2020-01-08 17:52:05 +08002166 if (cmd.remove_outer_tag()) {
2167 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
2168 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
2169 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05302170
Girish Gowdraf83e17a2022-02-16 16:27:00 -08002171 if (cmd.translate_outer_tag()) {
2172 OPENOLT_LOG(DEBUG, openolt_log_id, "action translate o_tag\n");
2173 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_XLATE_OUTER_TAG);
2174 }
2175
Jason Huang09b73ea2020-01-08 17:52:05 +08002176 if (action.o_vid()) {
2177 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
2178 o_vid = action.o_vid();
2179 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
2180 }
2181
2182 if (action.o_pbits()) {
2183 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
2184 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
2185 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05302186
Jason Huang09b73ea2020-01-08 17:52:05 +08002187 if (action.i_vid()) {
2188 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
2189 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
2190 }
2191
2192 if (action.i_pbits()) {
2193 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
2194 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
2195 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05302196
Jason Huang09b73ea2020-01-08 17:52:05 +08002197 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
2198
Burak Gurdaga0523592021-02-24 15:17:47 +00002199 if ((access_intf_id >= 0) && (onu_id >= ONU_ID_START)) {
Jason Huang09b73ea2020-01-08 17:52:05 +08002200 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
2201 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002202 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 +00002203
Jason Huang09b73ea2020-01-08 17:52:05 +08002204 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2205 // Queue 0 on DS subscriber scheduler
2206 tm_val.queue_id = 0;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002207
Jason Huang09b73ea2020-01-08 17:52:05 +08002208 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2209 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2210 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002211
Jason Huang09b73ea2020-01-08 17:52:05 +08002212 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2213 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2214 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002215
Jason Huang09b73ea2020-01-08 17:52:05 +08002216 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2217 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
2218 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 +00002219
Jason Huang09b73ea2020-01-08 17:52:05 +08002220 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2221 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2222 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2223 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 +00002224
Jason Huang09b73ea2020-01-08 17:52:05 +08002225 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2226 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2227 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2228 }
2229 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
2230 // NNI Scheduler ID
2231 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2232 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2233 // Queue 0 on NNI scheduler
2234 tm_val.queue_id = 0;
2235 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2236 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2237 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002238
Jason Huang09b73ea2020-01-08 17:52:05 +08002239 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 +00002240 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2241 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2242
Jason Huang09b73ea2020-01-08 17:52:05 +08002243 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2244 /* Fetch TM QMP ID mapped to US NNI scheduler */
2245 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2246 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2247 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2248 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2249 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 +00002250
Sridhar Ravindra57d7eb92025-06-04 13:39:43 +05302251 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, tm_qmp_id = %d, sched_id = %d, intf_type %s\n", \
2252 upstream.c_str(), tm_q_set_id, tm_qmp_id, tm_val.sched_id, \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002253 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002254 }
Shad Ansari39739bc2018-09-13 21:38:37 +00002255 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302256 } else {
2257 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2258 tm_val.queue_id = 0;
2259
2260 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2261 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2262 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2263
2264 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2265 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
2266 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00002267 }
2268
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002269 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002270
Girish Gowdra252f4972020-09-07 21:24:01 -07002271#ifndef SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002272 // BAL 3.1 supports statistics only for unicast flows.
2273 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
2274 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
2275 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002276#endif // SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002277
Girish Gowdra252f4972020-09-07 21:24:01 -07002278#ifndef SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002279#ifdef FLOW_CHECKER
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002280 //Flow Checker, To avoid duplicate flow.
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002281 if (flow_id_counters != 0) {
2282 bool b_duplicate_flow = false;
Jason Huang09b73ea2020-01-08 17:52:05 +08002283 std::map<flow_pair, int>::iterator it;
2284
2285 for(it = flow_map.begin(); it != flow_map.end(); it++) {
2286 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(it->first.first, it->first.second, ONU_ID)) && \
2287 (key.flow_type == it->first.second) && \
2288 (cfg.data.svc_port_id == get_flow_status(it->first.first, it->first.second, SVC_PORT_ID)) && \
2289 (cfg.data.priority == get_flow_status(it->first.first, it->first.second, PRIORITY)) && \
2290 (cfg.data.cookie == get_flow_status(it->first.first, it->first.second, COOKIE)) && \
2291 (cfg.data.ingress_intf.intf_type == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_TYPE)) && \
2292 (cfg.data.ingress_intf.intf_id == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_ID)) && \
2293 (cfg.data.egress_intf.intf_type == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_TYPE)) && \
2294 (cfg.data.egress_intf.intf_id == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_ID)) && \
2295 (c_val.o_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_VID)) && \
2296 (c_val.o_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_PBITS)) && \
2297 (c_val.i_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_VID)) && \
2298 (c_val.i_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_PBITS)) && \
2299 (c_val.ether_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_ETHER_TYPE)) && \
2300 (c_val.ip_proto == get_flow_status(it->first.first, it->first.second, CLASSIFIER_IP_PROTO)) && \
2301 (c_val.src_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_SRC_PORT)) && \
2302 (c_val.dst_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_DST_PORT)) && \
2303 (c_val.pkt_tag_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_PKT_TAG_TYPE)) && \
2304 (cfg.data.egress_qos.type == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TYPE)) && \
2305 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_QUEUE_ID)) && \
2306 (cfg.data.egress_qos.tm_sched.id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TM_SCHED_ID)) && \
2307 (a_val.cmds_bitmask == get_flow_status(it->first.first, it->first.second, ACTION_CMDS_BITMASK)) && \
2308 (a_val.o_vid == get_flow_status(it->first.first, it->first.second, ACTION_O_VID)) && \
2309 (a_val.i_vid == get_flow_status(it->first.first, it->first.second, ACTION_I_VID)) && \
2310 (a_val.o_pbits == get_flow_status(it->first.first, it->first.second, ACTION_O_PBITS)) && \
2311 (a_val.i_pbits == get_flow_status(it->first.first, it->first.second, ACTION_I_PBITS)) && \
2312 (cfg.data.state == get_flow_status(it->first.first, it->first.second, STATE)) && \
2313 (cfg.data.group_id == get_flow_status(it->first.first, it->first.second, GROUP_ID));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002314#ifdef SHOW_FLOW_PARAM
2315 // Flow Parameter
2316 FLOW_PARAM_LOG();
2317#endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002318 if (b_duplicate_flow) {
2319 FLOW_LOG(WARNING, "Flow duplicate", 0);
2320 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
2321 }
2322 }
2323 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002324#endif // FLOW_CHECKER
2325#endif // SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002326
2327 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2328 if (err) {
2329 FLOW_LOG(ERROR, "Flow add failed", err);
2330 return bcm_to_grpc_err(err, "flow add failed");
2331 } else {
2332 FLOW_LOG(INFO, "Flow add ok", err);
2333 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002334 flow_map[std::pair<int, int>(key.flow_id,key.flow_type)] = flow_map.size();
2335 flow_id_counters = flow_map.size();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002336 bcmos_fastlock_unlock(&data_lock, 0);
Girish Gowdra252f4972020-09-07 21:24:01 -07002337
2338 }
Burak Gurdaga0523592021-02-24 15:17:47 +00002339
2340 /*
2341 Enable AES encryption on GEM ports if they are used in downstream unicast flows.
2342 Rationale: We can't do upstream encryption in GPON. This change addresses the common denominator (and also minimum viable)
2343 use case for both technologies which is downstream unicast GEM port encryption. Since the downstream traffic is inherently
2344 broadcast to all the ONUs behind a PON port, encrypting the individual subscriber traffic in this direction is important
2345 and considered good enough in terms of security (See Section 12.1 of G.984.3). For upstream unicast and downstream multicast
2346 GEM encryption, we need to make additional changes specific to XGSPON. This will be done as a future work.
2347 */
2348 if (aes_enabled && (access_intf_id >= 0) && (gemport_id >= GEM_PORT_ID_START) && (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM)) {
2349 OPENOLT_LOG(INFO, openolt_log_id, "Setting encryption on pon = %d gem_port = %d through flow_id = %d\n", access_intf_id, gemport_id, flow_id);
Thiyagarajan Subramani19168f52021-05-25 23:26:41 +05302350 enable_encryption_for_gem_port(access_intf_id, gemport_id, board_technology);
Burak Gurdaga0523592021-02-24 15:17:47 +00002351 } else {
2352 OPENOLT_LOG(WARNING, openolt_log_id, "Flow config for flow_id = %d is not suitable for setting downstream encryption on pon = %d gem_port = %d. No action taken.\n", flow_id, access_intf_id, gemport_id);
2353 }
2354
Girish Gowdra252f4972020-09-07 21:24:01 -07002355 return Status::OK;
2356}
2357
2358Status FlowRemoveWrapper_(const ::openolt::Flow* request) {
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002359 int32_t access_intf_id = request->access_intf_id();
2360 int32_t onu_id = request->onu_id();
2361 int32_t uni_id = request->uni_id();
2362 uint32_t tech_profile_id = request->tech_profile_id();
Girish Gowdra252f4972020-09-07 21:24:01 -07002363 uint64_t voltha_flow_id = request->flow_id();
2364 Status st;
2365
2366 // If Voltha flow is not installed, return fail
2367 if (! is_voltha_flow_installed(voltha_flow_id)) {
2368 OPENOLT_LOG(ERROR, openolt_log_id, "voltha_flow_id=%lu not found\n", voltha_flow_id);
2369 return ::Status(grpc::StatusCode::NOT_FOUND, "voltha-flow-not-found");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002370 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04002371
Girish Gowdra252f4972020-09-07 21:24:01 -07002372 const device_flow *dev_fl = get_device_flow(voltha_flow_id);
2373 if (dev_fl == NULL) {
2374 OPENOLT_LOG(ERROR, openolt_log_id, "device flow for voltha_flow_id=%lu in the cache is NULL\n", voltha_flow_id);
2375 return ::Status(grpc::StatusCode::INTERNAL, "device-flow-null-in-cache");
2376 }
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002377 std::string flow_type = dev_fl->flow_type;
Girish Gowdra252f4972020-09-07 21:24:01 -07002378 if (dev_fl->is_flow_replicated) {
2379 // Note: Here we are ignoring FlowRemove failures
Girish Gowdra52997cc2022-06-02 20:58:50 -07002380 for (int i=0; i<dev_fl->total_replicated_flows; i++) {
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002381 st = FlowRemove_(dev_fl->params[i].flow_id, flow_type);
Girish Gowdra252f4972020-09-07 21:24:01 -07002382 if (st.error_code() == grpc::StatusCode::OK) {
2383 free_flow_id(dev_fl->params[i].flow_id);
2384 }
2385 }
2386 } else {
2387 // Note: Here we are ignoring FlowRemove failures
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002388 st = FlowRemove_(dev_fl->params[0].flow_id, flow_type);
Girish Gowdra252f4972020-09-07 21:24:01 -07002389 if (st.error_code() == grpc::StatusCode::OK) {
2390 free_flow_id(dev_fl->params[0].flow_id);
2391 }
2392 }
2393 // remove the flow from cache on voltha flow removal
2394 remove_voltha_flow_from_cache(voltha_flow_id);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002395
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002396 symmetric_datapath_flow_id_map_key key(access_intf_id, onu_id, uni_id, tech_profile_id, flow_type);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002397 // Remove onu-uni mapping for the pon-gem key
2398 bcmos_fastlock_lock(&symmetric_datapath_flow_id_lock);
2399 symmetric_datapath_flow_id_map.erase(key);
2400 bcmos_fastlock_unlock(&symmetric_datapath_flow_id_lock, 0);
2401
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002402 return Status::OK;
2403}
2404
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002405Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
2406
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002407 bcmolt_flow_cfg cfg;
2408 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002409
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002410 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002411 key.flow_id = flow_id;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002412 if (flow_type == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002413 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002414 } else if (flow_type == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002415 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002416 } else if(flow_type == multicast) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002417 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002418 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002419 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002420 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
2421 }
2422
Jason Huang09b73ea2020-01-08 17:52:05 +08002423 OPENOLT_LOG(INFO, openolt_log_id, "flow remove received for flow_id=%u, flow_type=%s\n",
2424 flow_id, flow_type.c_str());
2425
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002426 bcmos_fastlock_lock(&acl_packet_trap_handler_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002427 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
2428 int32_t gemport_id = -1;
2429 int32_t intf_id = -1;
2430 int16_t acl_id = -1;
2431 if (flow_to_acl_map.count(fl_id_fl_dir) > 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002432
2433 acl_id_intf_id ac_id_if_id = flow_to_acl_map[fl_id_fl_dir];
2434 acl_id = std::get<0>(ac_id_if_id);
2435 intf_id = std::get<1>(ac_id_if_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002436 // cleanup acl only if it is a valid acl. If not valid acl, it may be datapath flow.
2437 if (acl_id >= 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002438 Status resp = handle_acl_rule_cleanup(acl_id, intf_id, flow_type);
Jason Huang09b73ea2020-01-08 17:52:05 +08002439 if (resp.ok()) {
2440 OPENOLT_LOG(INFO, openolt_log_id, "acl removed ok for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2441 flow_to_acl_map.erase(fl_id_fl_dir);
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002442
2443 // When flow is being removed, extract the value corresponding to flow_id from trap_to_host_pkt_info_with_vlan_for_flow_id if it exists
2444 if (trap_to_host_pkt_info_with_vlan_for_flow_id.count(flow_id) > 0) {
2445 trap_to_host_pkt_info_with_vlan pkt_info_with_vlan = trap_to_host_pkt_info_with_vlan_for_flow_id[flow_id];
2446 // Formulate the trap_to_host_pkt_info tuple key
2447 trap_to_host_pkt_info pkt_info(std::get<0>(pkt_info_with_vlan),
2448 std::get<1>(pkt_info_with_vlan),
2449 std::get<2>(pkt_info_with_vlan),
2450 std::get<3>(pkt_info_with_vlan));
2451 // Extract the value corresponding to trap_to_host_pkt_info key from trap_to_host_vlan_ids_for_trap_to_host_pkt_info
2452 // The value is a list of vlan_ids for the given trap_to_host_pkt_info key
2453 // Remove the vlan_id from the list that corresponded to the flow being removed.
2454 if (trap_to_host_vlan_ids_for_trap_to_host_pkt_info.count(pkt_info) > 0) {
2455 trap_to_host_vlan_ids_for_trap_to_host_pkt_info[pkt_info].remove(std::get<4>(pkt_info_with_vlan));
2456 } else {
2457 OPENOLT_LOG(ERROR, openolt_log_id, "trap-to-host with intf_type = %d, intf_id = %d, pkt_type = %d gemport_id = %d not found in trap_to_host_vlan_ids_for_trap_to_host_pkt_info map",
2458 std::get<0>(pkt_info_with_vlan), std::get<1>(pkt_info_with_vlan), std::get<2>(pkt_info_with_vlan), std::get<3>(pkt_info_with_vlan));
2459 }
2460
2461 } else {
2462 OPENOLT_LOG(ERROR, openolt_log_id, "flow id = %u not found in trap_to_host_pkt_info_with_vlan_for_flow_id map", flow_id);
2463 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002464 } else {
2465 OPENOLT_LOG(ERROR, openolt_log_id, "acl remove error for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2466 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002467 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002468 return resp;
2469 }
2470 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002471 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002472
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002473 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002474 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002475 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002476 flowid_to_gemport.erase(key.flow_id);
2477 port_to_flows[port_no].erase(key.flow_id);
2478 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
2479 }
2480 else
2481 {
2482 flowid_to_port.erase(key.flow_id);
2483 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002484 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002485
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002486 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002487
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002488 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002489 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07002490 OPENOLT_LOG(ERROR, openolt_log_id, "Error while removing %s flow, flow_id=%d, err = %s (%d)\n", flow_type.c_str(), flow_id, cfg.hdr.hdr.err_text, err);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002491 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
2492 }
2493
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002494 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002495 if (flow_id_counters != 0) {
2496 std::map<flow_pair, int>::iterator it;
2497 for(it = flow_map.begin(); it != flow_map.end(); it++) {
2498 if (it->first.first == flow_id && it->first.second == key.flow_type) {
2499 flow_id_counters -= 1;
2500 flow_map.erase(it);
Shivanagouda Malaginahallie707d612023-08-22 10:40:25 +00002501 break; /* After match found break from the loop, otherwise leads to crash */
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002502 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002503 }
2504 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002505 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
2506
Jason Huang09b73ea2020-01-08 17:52:05 +08002507 flow_to_acl_map.erase(fl_id_fl_dir);
2508
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002509 bcmos_fastlock_unlock(&data_lock, 0);
2510
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002511 return Status::OK;
2512}
2513
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002514bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
2515 bcmos_errno err;
2516 bcmolt_tm_sched_cfg tm_sched_cfg;
2517 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2518 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
2519
Jason Huangbf45ffb2019-10-30 17:29:02 +08002520 //check TM scheduler has configured or not
2521 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2522 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002523 #ifdef TEST_MODE
2524 // It is impossible to mock the setting of tm_sched_cfg.data.state because
2525 // the actual bcmolt_cfg_get passes the address of tm_sched_cfg.hdr and we cannot
2526 // set the tm_sched_cfg.data.state. So a new stub function is created and address
2527 // of tm_sched_cfg is passed. This is one-of case where we need to add test specific
2528 // code in production code.
2529 err = bcmolt_cfg_get__tm_sched_stub(dev_id, &tm_sched_cfg);
2530 #else
Jason Huangbf45ffb2019-10-30 17:29:02 +08002531 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002532 #endif
Jason Huangbf45ffb2019-10-30 17:29:02 +08002533 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07002534 OPENOLT_LOG(ERROR, openolt_log_id, "cfg: Failed to query TM scheduler, err = %s (%d)\n", tm_sched_cfg.hdr.hdr.err_text, err);
Jason Huangbf45ffb2019-10-30 17:29:02 +08002535 return err;
2536 }
2537 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
2538 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
2539 return BCM_ERR_OK;
2540 }
2541
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002542 // bcmbal_tm_sched_owner
2543 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2544
2545 /**< The output of the tm_sched object instance */
2546 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
2547
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002548 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002549 // In upstream it is NNI scheduler
2550 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002551 } else if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002552 // In downstream it is PON scheduler
2553 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2554 }
2555
2556 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2557
2558 // bcmbal_tm_sched_type
2559 // set the deafult policy to strict priority
2560 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2561
2562 // num_priorities: Max number of strict priority scheduling elements
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002563 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, NUM_OF_PRIORITIES);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002564
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002565 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2566 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002567 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
2568 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002569 return err;
2570 }
2571
2572 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2573 direction.c_str(), tm_sched_key.id, intf_id);
2574 return BCM_ERR_OK;
2575}
2576
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002577bcmos_errno CreateSched(std::string direction, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t port_no,
Girish Gowdra252f4972020-09-07 21:24:01 -07002578 uint32_t alloc_id, ::tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
2579 ::tech_profile::SchedulingPolicy sched_policy, ::tech_profile::TrafficShapingInfo tf_sh_info,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002580 uint32_t tech_profile_id) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002581
2582 bcmos_errno err;
2583
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002584 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002585 bcmolt_tm_sched_cfg tm_sched_cfg;
2586 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002587 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 -04002588
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002589 // bcmbal_tm_sched_owner
2590 // In downstream it is sub_term scheduler
2591 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002592
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002593 /**< The output of the tm_sched object instance */
2594 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002595
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002596 // bcmbal_tm_sched_parent
2597 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2598 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
Girish Gowdra5287fde2021-07-31 00:41:45 +00002599 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002600 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 +00002601 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002602 be achieved using the' virtual' type of attachment.
2603 tm_sched_owner.u.sub_term.intf_id = intf_id;
2604 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2605 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002606
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002607 // bcmbal_tm_sched_type
2608 // set the deafult policy to strict priority
2609 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002610
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002611 // num_priorities: Max number of strict priority scheduling elements
2612 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002613
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002614 // bcmbal_tm_shaping
2615 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2616 uint32_t cir = tf_sh_info.cir();
2617 uint32_t pir = tf_sh_info.pir();
2618 uint32_t burst = tf_sh_info.pbs();
2619 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2620 cir, pir, burst);
2621 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2622 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2623 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2624 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2625 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2626 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002627 }
2628
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002629 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002630 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002631 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Girish Gowdra72cbee92021-11-05 15:16:18 -07002632intf_id %d, onu_id %d, uni_id %d, port_no %u, err = %s (%d)\n", tm_sched_key.id, intf_id, onu_id, uni_id, \
2633port_no, tm_sched_cfg.hdr.hdr.err_text, err);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002634 return err;
2635 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002636 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2637uni_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 -08002638
2639 } else { //upstream
Arthur Syu094df162022-04-21 17:50:06 +08002640 std::string intf_technology = intf_technologies[intf_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002641 bcmolt_itupon_alloc_cfg cfg;
2642 bcmolt_itupon_alloc_key key = { };
2643 key.pon_ni = intf_id;
2644 key.alloc_id = alloc_id;
Arthur Syu094df162022-04-21 17:50:06 +08002645 int bw_granularity = (intf_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
Burak Gurdag623fada2021-04-20 22:02:36 +00002646 /*
2647 PIR: Maximum Bandwidth
2648 CIR: Assured Bandwidth
2649 GIR: Fixed Bandwidth
2650 */
Burak Gurdag03919c72020-02-04 22:46:57 +00002651 int pir_bw = tf_sh_info.pir()*125; // conversion from kbps to bytes/sec
2652 int cir_bw = tf_sh_info.cir()*125; // conversion from kbps to bytes/sec
Burak Gurdag623fada2021-04-20 22:02:36 +00002653 int gir_bw = tf_sh_info.gir()*125; // conversion from kbps to bytes/sec
2654 int guaranteed_bw = cir_bw+gir_bw;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002655 //offset to match bandwidth granularity
2656 int offset_pir_bw = pir_bw%bw_granularity;
Burak Gurdag623fada2021-04-20 22:02:36 +00002657 int offset_gir_bw = gir_bw%bw_granularity;
2658 int offset_guaranteed_bw = guaranteed_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002659
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002660 pir_bw = pir_bw - offset_pir_bw;
Burak Gurdag623fada2021-04-20 22:02:36 +00002661 gir_bw = gir_bw - offset_gir_bw;
2662 guaranteed_bw = guaranteed_bw - offset_guaranteed_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002663
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002664 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002665
Burak Gurdag623fada2021-04-20 22:02:36 +00002666 OPENOLT_LOG(INFO, openolt_log_id, "Creating alloc_id %d with pir = %d bytes/sec, cir = %d bytes/sec, gir = %d bytes/sec, additional_bw = %d.\n", alloc_id, pir_bw, cir_bw, gir_bw, additional_bw);
2667
2668 if (pir_bw == 0) {
2669 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be at least %d bytes/sec\n",
2670 (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2671 return BCM_ERR_PARM;
2672 } else if (pir_bw < guaranteed_bw) {
2673 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed bandwidth (%d)\n",
2674 pir_bw, guaranteed_bw);
2675 return BCM_ERR_PARM;
2676 }
2677
2678 // Setting additional bw eligibility and validating bw provisionings
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002679 switch (additional_bw) {
Burak Gurdag623fada2021-04-20 22:02:36 +00002680
2681 case tech_profile::AdditionalBW::AdditionalBW_BestEffort: //AdditionalBW_BestEffort - For T-Cont types 4 & 5
2682 if (pir_bw == guaranteed_bw) {
2683 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2684bandwidth for additional bandwidth eligibility of type Best Effort\n");
2685 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002686 }
2687 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2688 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002689
2690 case tech_profile::AdditionalBW::AdditionalBW_NA: //AdditionalBW_NA - For T-Cont types 3 & 5
2691 if (guaranteed_bw == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002692 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2693additional bandwidth eligibility of type Non-Assured (NA)\n");
2694 return BCM_ERR_PARM;
Burak Gurdag623fada2021-04-20 22:02:36 +00002695 } else if (pir_bw == guaranteed_bw) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002696 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
Burak Gurdag623fada2021-04-20 22:02:36 +00002697bandwidth for additional bandwidth eligibility of type Non-Assured\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002698 return BCM_ERR_PARM;
2699 }
2700 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2701 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002702
2703 case tech_profile::AdditionalBW::AdditionalBW_None: //AdditionalBW_None - For T-Cont types 1 & 2
2704 if (guaranteed_bw != pir_bw) {
2705 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be equal to maximum bandwidth \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002706for additional bandwidth eligibility of type None\n");
2707 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002708 }
2709 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2710 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002711
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002712 default:
Burak Gurdag623fada2021-04-20 22:02:36 +00002713 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid additional bandwidth eligibility value (%d) supplied.\n", additional_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002714 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002715 }
Burak Gurdag623fada2021-04-20 22:02:36 +00002716
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002717 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2718 in a fine granularity. */
2719 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
Burak Gurdag623fada2021-04-20 22:02:36 +00002720 /* Since we can assign minimum 64000 bytes/sec for cbr_rt_bw, we prefer assigning
2721 gir_bw to cbr_nrt_bw to allow smaller amounts.
2722 TODO: Specify CBR_RT_BW and CBR_NRT_BW separately from VOLTHA */
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002723 /* Fixed Bandwidth with no critical requirement of shaping */
Burak Gurdag623fada2021-04-20 22:02:36 +00002724 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, gir_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002725 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
Burak Gurdag623fada2021-04-20 22:02:36 +00002726 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, guaranteed_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002727 /* Maximum allocated bandwidth allowed for this alloc ID */
2728 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
Burak Gurdag623fada2021-04-20 22:02:36 +00002729
2730 if (pir_bw == gir_bw) { // T-Cont Type 1 --> set alloc type to NONE
2731 // the condition cir_bw == 0 is implicitly satistied
2732 OPENOLT_LOG(INFO, openolt_log_id, "Setting alloc type to NONE since maximum bandwidth is equal to fixed bandwidth\n");
2733 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NONE);
2734 } else { // For other T-Cont types, set alloc type to NSR. TODO: read the default from a config file.
2735 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
2736 }
2737
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002738 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002739 for skipped allocations during quiet window */
2740 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2741 /**< Allocation Profile index for CBR non-RT Bandwidth */
2742 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2743 /**< Allocation Profile index for CBR RT Bandwidth */
2744 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2745 /**< Alloc ID Weight used in case of Extended DBA mode */
2746 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2747 /**< Alloc ID Priority used in case of Extended DBA mode */
2748 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2749 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002750
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302751 bcmolt_onu_state onu_state;
2752 bool wait_for_alloc_cfg_cmplt = false;
2753 err = get_onu_state((bcmolt_interface)intf_id, (bcmolt_onu_id)onu_id, &onu_state);
2754 if (err) {
2755 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch onu status, intf_id = %d, onu_id = %d, err = %s\n",
2756 intf_id, onu_id, bcmos_strerror(err));
2757 return err;
2758 } else if (onu_state == BCMOLT_ONU_STATE_ACTIVE) {
2759 wait_for_alloc_cfg_cmplt = true;
2760 }
2761
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002762 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002763 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002764 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
Girish Gowdra72cbee92021-11-05 15:16:18 -07002765port_no %u, alloc_id %d, err = %s (%d)\n", intf_id, onu_id,uni_id,port_no,alloc_id, cfg.hdr.hdr.err_text, err);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002766 return err;
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302767 } else if (wait_for_alloc_cfg_cmplt) {
2768 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
2769 if (err) {
2770 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
Girish Gowdra96461052019-11-22 20:13:59 +05302771port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302772 return err;
Girish Gowdra72cbee92021-11-05 15:16:18 -07002773 }
2774 } else {
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302775 OPENOLT_LOG(INFO, openolt_log_id, "onu not active, not waiting for alloc cfg complete, onu_state = %d, intf = %d, onu=%d\n",
2776 onu_state, intf_id, onu_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302777 }
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302778
Girish Gowdra96461052019-11-22 20:13:59 +05302779 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
2780port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
2781
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002782 }
2783
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002784 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002785}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002786
Girish Gowdra252f4972020-09-07 21:24:01 -07002787Status CreateTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002788 uint32_t intf_id = traffic_scheds->intf_id();
2789 uint32_t onu_id = traffic_scheds->onu_id();
2790 uint32_t uni_id = traffic_scheds->uni_id();
2791 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002792 std::string direction;
2793 unsigned int alloc_id;
Girish Gowdra252f4972020-09-07 21:24:01 -07002794 ::tech_profile::SchedulerConfig sched_config;
2795 ::tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002796 uint32_t priority;
2797 uint32_t weight;
Girish Gowdra252f4972020-09-07 21:24:01 -07002798 ::tech_profile::SchedulingPolicy sched_policy;
2799 ::tech_profile::TrafficShapingInfo traffic_shaping_info;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002800 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002801 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002802
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002803 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002804 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002805
2806 direction = GetDirection(traffic_sched.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002807 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002808 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002809 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002810
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002811 alloc_id = traffic_sched.alloc_id();
2812 sched_config = traffic_sched.scheduler();
2813 additional_bw = sched_config.additional_bw();
2814 priority = sched_config.priority();
2815 weight = sched_config.weight();
2816 sched_policy = sched_config.sched_policy();
2817 traffic_shaping_info = traffic_sched.traffic_shaping_info();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002818 tech_profile_id = traffic_sched.tech_profile_id();
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002819 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002820 sched_policy, traffic_shaping_info, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002821 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002822 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002823 return bcm_to_grpc_err(err, "Failed to create scheduler");
2824 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002825 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002826 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002827}
Jonathan Davis70c21812018-07-19 15:32:10 -04002828
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002829bcmos_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 -04002830
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002831 bcmos_errno err;
Girish Gowdra72cbee92021-11-05 15:16:18 -07002832 bcmolt_onu_state onu_state;
Girish Gowdra96461052019-11-22 20:13:59 +05302833 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002834
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002835 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002836 bcmolt_itupon_alloc_cfg cfg;
2837 bcmolt_itupon_alloc_key key = { };
2838 key.pon_ni = intf_id;
2839 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302840 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002841
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302842 bcmolt_onu_state onu_state;
2843 bool wait_for_alloc_cfg_cmplt = false;
2844 err = get_onu_state((bcmolt_interface)intf_id, (bcmolt_onu_id)onu_id, &onu_state);
2845 if (err) {
2846 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch onu status, intf_id = %d, onu_id = %d, err = %s\n",
2847 intf_id, onu_id, bcmos_strerror(err));
2848 return err;
2849 } else if (onu_state == BCMOLT_ONU_STATE_ACTIVE) {
2850 wait_for_alloc_cfg_cmplt = true;
2851 }
2852
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002853 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002854 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2855 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07002856 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s (%d)\n",
2857 direction.c_str(), intf_id, alloc_id, cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002858 return err;
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302859 } else if (wait_for_alloc_cfg_cmplt) {
2860 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2861 if (err) {
2862 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2863pon_intf %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,intf_id,alloc_id, bcmos_strerror(err));
2864 return err;
2865 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302866 } else {
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302867 OPENOLT_LOG(INFO, openolt_log_id, "onu not active, not waiting for alloc cfg complete, onu_state = %d, intf = %d, onu=%d\n",
2868 onu_state, intf_id, onu_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302869 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002870 } else if (direction == downstream) {
2871 bcmolt_tm_sched_cfg cfg;
2872 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002873
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002874 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2875 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302876 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002877 } else {
2878 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2879 return BCM_ERR_OK;
2880 }
Girish Gowdra96461052019-11-22 20:13:59 +05302881
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002882 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2883 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2884 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002885 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
Girish Gowdra72cbee92021-11-05 15:16:18 -07002886intf_id %d, onu_id %d, tech_profile_id %d, err = %s (%d)\n", direction.c_str(), key.id, intf_id, onu_id, tech_profile_id, cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002887 return err;
2888 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002889 }
2890
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002891 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d, tech_profile_id %d\n",
2892 direction.c_str(), sched_id, intf_id, onu_id, tech_profile_id);
2893 free_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002894 return BCM_ERR_OK;
2895}
2896
Girish Gowdra252f4972020-09-07 21:24:01 -07002897Status RemoveTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002898 uint32_t intf_id = traffic_scheds->intf_id();
2899 uint32_t onu_id = traffic_scheds->onu_id();
2900 uint32_t uni_id = traffic_scheds->uni_id();
2901 std::string direction;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002902 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002903 bcmos_errno err;
2904
2905 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002906 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002907
2908 direction = GetDirection(traffic_sched.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002909 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002910 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002911 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002912
2913 int alloc_id = traffic_sched.alloc_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002914 int tech_profile_id = traffic_sched.tech_profile_id();
2915 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002916 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002917 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002918 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2919 }
2920 }
2921 return Status::OK;
2922}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002923
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002924bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2925 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002926 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002927 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2928 bcmolt_tm_qmp_key tm_qmp_key;
2929 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002930
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002931 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2932 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002933 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed tm queue mapping profile count is 16.\n");
2934 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002935 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002936
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002937 tm_qmp_key.id = tm_qmp_id;
2938 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2939 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2940 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002941
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002942 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2943 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2944 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002945 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2946 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002947
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002948 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002949 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002950 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2951 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002952 return err;
2953 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002954
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002955 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2956 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002957 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002958}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002959
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002960bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2961 bcmos_errno err;
2962 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2963 bcmolt_tm_qmp_key tm_qmp_key;
2964 tm_qmp_key.id = tm_qmp_id;
2965
2966 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2967 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2968 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002969 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2970 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002971 return err;
2972 }
2973
2974 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2975 tm_qmp_key.id);
2976 return BCM_ERR_OK;
2977}
2978
2979bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2980 bcmos_errno err;
2981
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002982 /* Create default queues on the given PON/NNI scheduler */
2983 for (int queue_id = 0; queue_id < NUMBER_OF_DEFAULT_INTERFACE_QUEUES; queue_id++) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002984 bcmolt_tm_queue_cfg tm_queue_cfg;
2985 bcmolt_tm_queue_key tm_queue_key = {};
2986 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2987 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002988 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2989 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2990 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002991
2992 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2993 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2994 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2995
2996 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2997 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002998 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", \
2999 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 +00003000 return err;
3001 }
3002
3003 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
3004 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
3005 }
3006 return BCM_ERR_OK;
3007}
3008
Sridhar Ravindra57d7eb92025-06-04 13:39:43 +05303009bcmos_errno CreateQueue(std::string direction, uint32_t nni_intf_id, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00003010 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 +00003011 bcmos_errno err;
3012 bcmolt_tm_queue_cfg cfg;
3013 bcmolt_tm_queue_key key = { };
Sridhar Ravindra57d7eb92025-06-04 13:39:43 +05303014 OPENOLT_LOG(INFO, openolt_log_id, "creating %s queue. access_intf_id = %d, nni_intf_id = %d, onu_id = %d, uni_id = %d \
3015gemport_id = %d, tech_profile_id = %d\n", direction.c_str(), access_intf_id, nni_intf_id, onu_id, uni_id, gemport_id, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003016
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08003017 key.sched_id = (direction == upstream) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00003018 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003019
3020 if (priority > 7) {
3021 return BCM_ERR_RANGE;
3022 }
3023
3024 /* FIXME: The upstream queues have to be created once only.
3025 The upstream queues on the NNI scheduler are shared by all subscribers.
3026 When the first scheduler comes in, the queues get created, and are re-used by all others.
3027 Also, these queues should be present until the last subscriber exits the system.
3028 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
3029
3030 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
3031 for each GEM in TECH PROFILE */
3032 key.id = queue_id_list[priority];
3033
3034 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
3035 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
3036 key.id = 0;
3037 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
3038 }
3039 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
3040 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
3041 }
3042 else {
3043 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
3044 }
3045
3046 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
3047
3048 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
3049 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
Girish Gowdra5287fde2021-07-31 00:41:45 +00003050 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003051
3052 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
3053 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003054 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
Girish Gowdra72cbee92021-11-05 15:16:18 -07003055sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, tech_profile_id %d, err = %s (%d)\n", \
3056 direction.c_str(), key.id, key.sched_id, key.tm_q_set_id, access_intf_id, onu_id, uni_id, tech_profile_id, cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003057 return err;
3058 }
3059
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05303060 if (direction == upstream || direction == downstream) {
Thiyagarajan Subramani19168f52021-05-25 23:26:41 +05303061 Status st = install_gem_port(access_intf_id, onu_id, uni_id, gemport_id, board_technology);
Girish Gowdra252f4972020-09-07 21:24:01 -07003062 if (st.error_code() != grpc::StatusCode::ALREADY_EXISTS && st.error_code() != grpc::StatusCode::OK) {
3063 OPENOLT_LOG(ERROR, openolt_log_id, "failed to created gemport=%d, access_intf=%d, onu_id=%d\n", gemport_id, access_intf_id, onu_id);
3064 return BCM_ERR_INTERNAL;
3065 }
Girish Gowdraeec0fc92021-05-12 15:37:55 -07003066 if (direction == upstream) {
3067 // Create the pon-gem to onu-uni mapping
3068 pon_gem pg(access_intf_id, gemport_id);
3069 onu_uni ou(onu_id, uni_id);
3070 bcmos_fastlock_lock(&pon_gem_to_onu_uni_map_lock);
3071 pon_gem_to_onu_uni_map[pg] = ou;
3072 bcmos_fastlock_unlock(&pon_gem_to_onu_uni_map_lock, 0);
3073 }
Girish Gowdra252f4972020-09-07 21:24:01 -07003074 }
3075
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003076 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 +00003077intf_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 +00003078 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003079}
3080
Girish Gowdra252f4972020-09-07 21:24:01 -07003081Status CreateTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003082 uint32_t intf_id = traffic_queues->intf_id();
Sridhar Ravindra57d7eb92025-06-04 13:39:43 +05303083 uint32_t nni_intf_id = traffic_queues->network_intf_id();
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003084 uint32_t onu_id = traffic_queues->onu_id();
3085 uint32_t uni_id = traffic_queues->uni_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00003086 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003087 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003088 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003089 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003090 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 +00003091
Sridhar Ravindra57d7eb92025-06-04 13:39:43 +05303092 OPENOLT_LOG(DEBUG, openolt_log_id, "Create traffic queues nni_intf_id %d, intf_id %d\n", nni_intf_id, intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003093 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
3094 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
3095 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
3096 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07003097 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003098
3099 direction = GetDirection(traffic_queue.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08003100 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003101 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08003102 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003103
3104 queues_priority_q[i] = traffic_queue.priority();
3105 queues_pbit_map[i] = traffic_queue.pbit_map();
3106 }
3107
3108 std::vector<uint32_t> tmq_map_profile(8, 0);
3109 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
3110 queues_priority_q, COUNT_OF(queues_priority_q));
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08003111 sched_id = (direction == upstream) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00003112 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003113
3114 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
3115 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05003116 err = CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
3117 if (err != BCM_ERR_OK) {
3118 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, err = %s\n", bcmos_strerror(err));
3119 return bcm_to_grpc_err(err, "Failed to create tm queue mapping profile");
3120 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003121 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
3122 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
3123 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
3124 }
3125 }
3126
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003127 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07003128 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003129
3130 direction = GetDirection(traffic_queue.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08003131 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003132 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08003133 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003134
Sridhar Ravindra57d7eb92025-06-04 13:39:43 +05303135 err = CreateQueue(direction, nni_intf_id, 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 +00003136
Girish Gowdruf26cf882019-05-01 23:47:58 -07003137 // If the queue exists already, lets not return failure and break the loop.
3138 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003139 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003140 return bcm_to_grpc_err(err, "Failed to create queue");
3141 }
3142 }
3143 return Status::OK;
3144}
3145
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003146bcmos_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 +00003147 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 +00003148 bcmolt_tm_queue_cfg cfg;
3149 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003150 bcmos_errno err;
3151
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05303152 // Gemports are bi-directional (except in multicast case). We create the gem port when we create the
3153 // upstream/downstream queue (see CreateQueue function) and it makes sense to delete them when remove the queues.
3154 // For multicast case we do not manage the install/remove of gem port in agent application. It is managed by BAL.
3155 if (direction == upstream || direction == downstream) {
Thiyagarajan Subramani19168f52021-05-25 23:26:41 +05303156 Status st = remove_gem_port(access_intf_id, onu_id, uni_id, gemport_id, board_technology);
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05303157 if (st.error_code() != grpc::StatusCode::OK) {
3158 OPENOLT_LOG(ERROR, openolt_log_id, "failed to remove gemport=%d, access_intf=%d, onu_id=%d\n", gemport_id, access_intf_id, onu_id);
Girish Gowdra72cbee92021-11-05 15:16:18 -07003159 // We should further cleanup proceed, do not return error yet..
3160 // return BCM_ERR_INTERNAL;
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05303161 }
Girish Gowdraeec0fc92021-05-12 15:37:55 -07003162 if (direction == upstream) {
3163 // Remove the pon-gem to onu-uni mapping
3164 pon_gem pg(access_intf_id, gemport_id);
3165 bcmos_fastlock_lock(&pon_gem_to_onu_uni_map_lock);
3166 pon_gem_to_onu_uni_map.erase(pg);
3167 bcmos_fastlock_unlock(&pon_gem_to_onu_uni_map_lock, 0);
3168 }
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05303169 }
3170
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003171 if (direction == downstream) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00003172 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction, tech_profile_id)) {
3173 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 +00003174 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003175 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003176 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 -08003177 return BCM_ERR_OK;
3178 }
3179 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003180 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
3181 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003182 return BCM_ERR_OK;
3183 }
3184
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003185 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
3186 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
3187 // Reset the queue id to 0 when using fixed queue.
3188 key.id = 0;
3189 }
3190 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
3191 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
3192 }
3193 else {
3194 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
3195 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003196
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003197 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
3198 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003199 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003200 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, queue_id %d, sched_id %d, \
Girish Gowdra72cbee92021-11-05 15:16:18 -07003201tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s (%d)\n",
3202 direction.c_str(), key.id, key.sched_id, key.tm_q_set_id, access_intf_id, onu_id, uni_id, cfg.hdr.hdr.err_text, err);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003203 return err;
3204 }
3205
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003206 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
3207intf_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 -08003208
3209 return BCM_ERR_OK;
3210}
3211
Girish Gowdra252f4972020-09-07 21:24:01 -07003212Status RemoveTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003213 uint32_t intf_id = traffic_queues->intf_id();
Sridhar Ravindra57d7eb92025-06-04 13:39:43 +05303214 uint32_t nni_intf_id = traffic_queues->network_intf_id();
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003215 uint32_t onu_id = traffic_queues->onu_id();
3216 uint32_t uni_id = traffic_queues->uni_id();
3217 uint32_t port_no = traffic_queues->port_no();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00003218 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003219 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003220 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003221 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003222 bcmolt_egress_qos_type qos_type = get_qos_type(intf_id, onu_id, uni_id, traffic_queues->traffic_queues_size());
Girish Gowdra72cbee92021-11-05 15:16:18 -07003223 Status ret_code = Status::OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003224
Sridhar Ravindra57d7eb92025-06-04 13:39:43 +05303225 OPENOLT_LOG(DEBUG, openolt_log_id, "Remove Traffic Queues for nni_intf_id %d, intf_id %d\n", nni_intf_id, intf_id);
3226
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003227 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07003228 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003229
3230 direction = GetDirection(traffic_queue.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08003231 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003232 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08003233 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003234
Burak Gurdag2f2618c2020-04-23 13:20:30 +00003235 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 -08003236 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003237 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdra72cbee92021-11-05 15:16:18 -07003238 ret_code = bcm_to_grpc_err(err, "Failed to remove one or more queues");
3239 // Do not return here. We should continue to remove the remaining queues and its associated gem ports
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003240 }
Jonathan Davis70c21812018-07-19 15:32:10 -04003241 }
3242
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08003243 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE && (direction == upstream || \
3244 direction == downstream && is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id))) {
3245 sched_id = (direction == upstream) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00003246 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003247
3248 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
3249 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05003250 err = RemoveTrafficQueueMappingProfile(tm_qmp_id);
3251 if (err != BCM_ERR_OK) {
3252 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, err = %s\n", bcmos_strerror(err));
3253 return bcm_to_grpc_err(err, "Failed to remove tm queue mapping profile");
3254 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003255 }
3256 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003257 clear_qos_type(intf_id, onu_id, uni_id);
Girish Gowdra72cbee92021-11-05 15:16:18 -07003258 return ret_code;
Jonathan Davis70c21812018-07-19 15:32:10 -04003259}
Jason Huangbf45ffb2019-10-30 17:29:02 +08003260
Girish Gowdra252f4972020-09-07 21:24:01 -07003261Status PerformGroupOperation_(const ::openolt::Group *group_cfg) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003262
3263 bcmos_errno err;
3264 bcmolt_group_key key = {};
3265 bcmolt_group_cfg grp_cfg_obj;
3266 bcmolt_group_members_update grp_mem_upd;
3267 bcmolt_members_update_command grp_mem_upd_cmd;
3268 bcmolt_group_member_info member_info = {};
3269 bcmolt_group_member_info_list_u8 members = {};
3270 bcmolt_intf_ref interface_ref = {};
3271 bcmolt_egress_qos egress_qos = {};
3272 bcmolt_tm_sched_ref tm_sched_ref = {};
3273 bcmolt_action a_val = {};
3274
3275 uint32_t group_id = group_cfg->group_id();
3276
3277 OPENOLT_LOG(INFO, openolt_log_id, "PerformGroupOperation request received for Group %d\n", group_id);
3278
3279 if (group_id >= 0) {
3280 key.id = group_id;
3281 }
3282 else {
3283 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
3284 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
3285 }
3286
3287 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3288 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
3289
3290 OPENOLT_LOG(INFO, openolt_log_id, "Checking if Group %d exists...\n",group_id);
3291
3292 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
3293 if (err != BCM_ERR_OK) {
3294 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
3295 return bcm_to_grpc_err(err, "Error in querying group");
3296 }
3297
3298 members.len = group_cfg->members_size();
3299
3300 // IMPORTANT: A member cannot be added to a group if the group type is not determined.
3301 // Group type is determined after a flow is assigned to it.
3302 // Therefore, a group must be created first, then a flow (with multicast type) must be assigned to it.
3303 // Only then we can add members to the group.
3304
3305 // if group does not exist, create it and return.
3306 if (grp_cfg_obj.data.state == BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
3307
3308 if (members.len != 0) {
3309 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);
3310 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Non-empty member list given for non-existent group");
3311 } else {
3312
3313 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3314 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, cookie, key.id);
3315
3316 /* Setting group actions and action parameters, if any.
3317 Only remove_outer_tag and translate_inner_tag actions and i_vid action parameter
3318 are supported for multicast groups in BAL 3.1.
3319 */
3320 const ::openolt::Action& action = group_cfg->action();
3321 const ::openolt::ActionCmd &cmd = action.cmd();
3322
3323 bcmolt_action_cmd_id cmd_bmask = BCMOLT_ACTION_CMD_ID_NONE;
3324 if (cmd.remove_outer_tag()) {
3325 OPENOLT_LOG(INFO, openolt_log_id, "Action remove_outer_tag applied to Group %d.\n", group_id);
3326 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
3327 }
3328
3329 if (cmd.translate_inner_tag()) {
3330 OPENOLT_LOG(INFO, openolt_log_id, "Action translate_inner_tag applied to Group %d.\n", group_id);
3331 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG);
3332 }
3333
3334 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, cmd_bmask);
3335
3336 if (action.i_vid()) {
3337 OPENOLT_LOG(INFO, openolt_log_id, "Setting action parameter i_vid=%d for Group %d.\n", action.i_vid(), group_id);
3338 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
3339 }
3340
3341 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, action, a_val);
3342
3343 // Create group
3344 err = bcmolt_cfg_set(dev_id, &(grp_cfg_obj.hdr));
3345
3346 if (BCM_ERR_OK != err) {
3347 BCM_LOG(ERROR, openolt_log_id, "Failed to create Group %d, err = %s (%d)\n", key.id, bcmos_strerror(err), err);
3348 return bcm_to_grpc_err(err, "Error in creating group");
3349 }
3350
3351 BCM_LOG(INFO, openolt_log_id, "Group %d has been created and configured with empty member list.\n", key.id);
3352 return Status::OK;
3353 }
3354 }
3355
3356 // The group already exists. Continue configuring it according to the update member command.
3357
3358 OPENOLT_LOG(INFO, openolt_log_id, "Configuring existing Group %d.\n",group_id);
3359
3360 // MEMBER LIST CONSTRUCTION
3361 // Note that members.len can be 0 here. if the group already exists and the command is SET then sending
3362 // empty list to the group is a legit operation and this actually empties the member list.
3363 members.arr = (bcmolt_group_member_info*)bcmos_calloc((members.len)*sizeof(bcmolt_group_member_info));
3364
3365 if (!members.arr) {
3366 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to allocate memory for group member list.\n");
3367 return grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "Memory exhausted during member list creation");
3368 }
3369
3370 /* SET GROUP MEMBERS UPDATE COMMAND */
Girish Gowdra252f4972020-09-07 21:24:01 -07003371 ::openolt::Group::GroupMembersCommand command = group_cfg->command();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003372 switch(command) {
Girish Gowdra252f4972020-09-07 21:24:01 -07003373 case ::openolt::Group::SET_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003374 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_SET;
3375 OPENOLT_LOG(INFO, openolt_log_id, "Setting %d members for Group %d.\n", members.len, group_id);
3376 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003377 case ::openolt::Group::ADD_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003378 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_ADD;
3379 OPENOLT_LOG(INFO, openolt_log_id, "Adding %d members to Group %d.\n", members.len, group_id);
3380 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003381 case ::openolt::Group::REMOVE_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003382 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_REMOVE;
3383 OPENOLT_LOG(INFO, openolt_log_id, "Removing %d members from Group %d.\n", members.len, group_id);
3384 break;
3385 default :
3386 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid value %d for group member command.\n", command);
3387 bcmos_free(members.arr);
3388 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group member command");
3389 }
3390
3391 // SET MEMBERS LIST
3392 for (int i = 0; i < members.len; i++) {
3393
Girish Gowdra252f4972020-09-07 21:24:01 -07003394 if (command == ::openolt::Group::REMOVE_MEMBERS) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003395 OPENOLT_LOG(INFO, openolt_log_id, "Removing group member %d from group %d\n",i,key.id);
3396 } else {
3397 OPENOLT_LOG(INFO, openolt_log_id, "Adding group member %d to group %d\n",i,key.id);
3398 }
3399
Girish Gowdra252f4972020-09-07 21:24:01 -07003400 ::openolt::GroupMember *member = (::openolt::GroupMember *) &group_cfg->members()[i];
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003401
3402 // Set member interface type
Girish Gowdra252f4972020-09-07 21:24:01 -07003403 ::openolt::GroupMember::InterfaceType if_type = member->interface_type();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003404 switch(if_type){
Girish Gowdra252f4972020-09-07 21:24:01 -07003405 case ::openolt::GroupMember::PON :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003406 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_PON);
3407 OPENOLT_LOG(INFO, openolt_log_id, "Interface type PON is assigned to GroupMember %d\n",i);
3408 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003409 case ::openolt::GroupMember::EPON_1G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003410 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_1_G);
3411 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_1G is assigned to GroupMember %d\n",i);
3412 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003413 case ::openolt::GroupMember::EPON_10G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003414 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_10_G);
3415 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_10G is assigned to GroupMember %d\n",i);
3416 break;
3417 default :
3418 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid interface type value %d for GroupMember %d.\n",if_type,i);
3419 bcmos_free(members.arr);
3420 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface type for a group member");
3421 }
3422
3423 // Set member interface id
3424 if (member->interface_id() >= 0) {
3425 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_id, member->interface_id());
3426 OPENOLT_LOG(INFO, openolt_log_id, "Interface %d is assigned to GroupMember %d\n", member->interface_id(), i);
3427 } else {
3428 bcmos_free(members.arr);
3429 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface id for a group member");
3430 }
3431
3432 // Set member interface_ref
3433 BCMOLT_FIELD_SET(&member_info, group_member_info, intf, interface_ref);
3434
3435 // Set member gem_port_id. This must be a multicast gemport.
3436 if (member->gem_port_id() >= 0) {
3437 BCMOLT_FIELD_SET(&member_info, group_member_info, svc_port_id, member->gem_port_id());
3438 OPENOLT_LOG(INFO, openolt_log_id, "GEM Port %d is assigned to GroupMember %d\n", member->gem_port_id(), i);
3439 } else {
3440 bcmos_free(members.arr);
3441 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid gem port id for a group member");
3442 }
3443
3444 // Set member scheduler id and queue_id
3445 uint32_t tm_sched_id = get_default_tm_sched_id(member->interface_id(), downstream);
3446 OPENOLT_LOG(INFO, openolt_log_id, "Scheduler %d is assigned to GroupMember %d\n", tm_sched_id, i);
3447 BCMOLT_FIELD_SET(&tm_sched_ref, tm_sched_ref, id, tm_sched_id);
3448 BCMOLT_FIELD_SET(&egress_qos, egress_qos, tm_sched, tm_sched_ref);
3449
3450 // We assume that all multicast traffic destined to a PON port is using the same fixed queue.
3451 uint32_t tm_queue_id;
3452 if (member->priority() >= 0 && member->priority() < NUMBER_OF_DEFAULT_INTERFACE_QUEUES) {
3453 tm_queue_id = queue_id_list[member->priority()];
3454 OPENOLT_LOG(INFO, openolt_log_id, "Queue %d is assigned to GroupMember %d\n", tm_queue_id, i);
3455 BCMOLT_FIELD_SET(&egress_qos, egress_qos, type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
3456 BCMOLT_FIELD_SET(&egress_qos.u.fixed_queue, egress_qos_fixed_queue, queue_id, tm_queue_id);
3457 } else {
3458 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid fixed queue priority/ID %d for GroupMember %d\n", member->priority(), i);
3459 bcmos_free(members.arr);
3460 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid queue priority for a group member");
3461 }
3462
3463 BCMOLT_FIELD_SET(&member_info, group_member_info, egress_qos, egress_qos);
3464 BCMOLT_ARRAY_ELEM_SET(&(members), i, member_info);
3465 }
3466
3467 BCMOLT_OPER_INIT(&grp_mem_upd, group, members_update, key);
3468 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.members, members);
3469 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.command, grp_mem_upd_cmd);
3470
3471 err = bcmolt_oper_submit(dev_id, &(grp_mem_upd.hdr));
3472 bcmos_free(members.arr);
3473
3474 if (BCM_ERR_OK != err) {
3475 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);
3476 return bcm_to_grpc_err(err, "Failed to submit members update operation for the group");
3477 }
3478
3479 OPENOLT_LOG(INFO, openolt_log_id, "Successfully submitted members update operation for Group %d\n", key.id);
3480
3481 return Status::OK;
3482}
Burak Gurdageb4ca2e2020-06-15 07:48:26 +00003483
3484Status DeleteGroup_(uint32_t group_id) {
3485
3486 bcmos_errno err = BCM_ERR_OK;
3487 bcmolt_group_cfg grp_cfg_obj;
3488 bcmolt_group_key key = {};
3489
3490
3491 OPENOLT_LOG(INFO, openolt_log_id, "Delete request received for group %d\n", group_id);
3492
3493 if (group_id >= 0) {
3494 key.id = group_id;
3495 } else {
3496 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
3497 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
3498 }
3499
3500 /* init the BAL INIT API */
3501 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3502
3503 OPENOLT_LOG(DEBUG, openolt_log_id, "Checking if group %d exists...\n",group_id);
3504
3505 // CONFIGURE GROUP MEMBERS
3506 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
3507 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
3508
3509 if (err != BCM_ERR_OK) {
3510 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
3511 return bcm_to_grpc_err(err, "Error in querying group");
3512 }
3513
3514 if (grp_cfg_obj.data.state != BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
3515 OPENOLT_LOG(DEBUG, openolt_log_id, "Group %d exists. Will be deleted.\n",group_id);
3516 err = bcmolt_cfg_clear(dev_id, &(grp_cfg_obj.hdr));
3517 if (err != BCM_ERR_OK) {
3518 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d cannot be deleted err = %s (%d).\n", group_id, bcmos_strerror(err), err);
3519 return bcm_to_grpc_err(err, "Failed to delete group");;
3520 }
3521 } else {
3522 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d does not exist.\n", group_id);
3523 return Status(grpc::StatusCode::NOT_FOUND, "Group not found");
3524 }
3525
3526 OPENOLT_LOG(INFO, openolt_log_id, "Group %d has been deleted successfully.\n", group_id);
3527 return Status::OK;
Jason Huang1d9cfce2020-05-20 22:58:47 +08003528}
3529
Girish Gowdra252f4972020-09-07 21:24:01 -07003530Status GetLogicalOnuDistanceZero_(uint32_t intf_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003531 bcmos_errno err = BCM_ERR_OK;
3532 uint32_t mld = 0;
3533 double LD0;
3534
3535 err = getOnuMaxLogicalDistance(intf_id, &mld);
3536 if (err != BCM_ERR_OK) {
3537 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3538 }
3539
3540 LD0 = LOGICAL_DISTANCE(mld*1000, MINIMUM_ONU_RESPONSE_RANGING_TIME, ONU_BIT_TRANSMISSION_DELAY);
3541 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance zero is %f, (PON %d)\n", LD0, intf_id);
3542 response->set_intf_id(intf_id);
3543 response->set_logical_onu_distance_zero(LD0);
3544
3545 return Status::OK;
3546}
3547
Girish Gowdra252f4972020-09-07 21:24:01 -07003548Status GetLogicalOnuDistance_(uint32_t intf_id, uint32_t onu_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003549 bcmos_errno err = BCM_ERR_OK;
3550 bcmolt_itu_onu_params itu = {};
3551 bcmolt_onu_cfg onu_cfg;
3552 bcmolt_onu_key onu_key = {};
3553 uint32_t mld = 0;
3554 double LDi;
3555
3556 onu_key.pon_ni = intf_id;
3557 onu_key.onu_id = onu_id;
3558
3559 err = getOnuMaxLogicalDistance(intf_id, &mld);
3560 if (err != BCM_ERR_OK) {
3561 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3562 }
3563
3564 /* Initialize the API struct. */
3565 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
3566 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
3567 BCMOLT_FIELD_SET_PRESENT(&itu, itu_onu_params, ranging_time);
3568 BCMOLT_FIELD_SET(&onu_cfg.data, onu_cfg_data, itu, itu);
3569 #ifdef TEST_MODE
3570 // It is impossible to mock the setting of onu_cfg.data.onu_state because
3571 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
3572 // set the onu_cfg.data.onu_state. So a new stub function is created and address
3573 // of onu_cfg is passed. This is one-of case where we need to add test specific
3574 // code in production code.
3575 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
3576 #else
3577 /* Call API function. */
3578 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
3579 #endif
3580 if (err != BCM_ERR_OK) {
3581 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);
3582 return bcm_to_grpc_err(err, "Failed to retrieve ONU ranging time");
3583 }
3584
3585 if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_ACTIVE) {
3586 OPENOLT_LOG(ERROR, openolt_log_id, "ONU is not yet activated (PON %d, ONU id %d)\n", intf_id, onu_id);
3587 return bcm_to_grpc_err(BCM_ERR_PARM, "ONU is not yet activated\n");
3588 }
3589
3590 LDi = LOGICAL_DISTANCE(mld*1000, onu_cfg.data.itu.ranging_time, ONU_BIT_TRANSMISSION_DELAY);
3591 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance is %f, (PON %d, ONU id %d)\n", LDi, intf_id, onu_id);
3592 response->set_intf_id(intf_id);
3593 response->set_onu_id(onu_id);
3594 response->set_logical_onu_distance(LDi);
3595
3596 return Status::OK;
3597}
Burak Gurdag74e3ab82020-12-17 13:35:06 +00003598
3599Status GetOnuStatistics_(uint32_t intf_id, uint32_t onu_id, openolt::OnuStatistics* onu_stats) {
3600 bcmos_errno err;
3601
3602 err = get_onu_statistics((bcmolt_interface_id)intf_id, (bcmolt_onu_id)onu_id, onu_stats);
3603
3604 if (err != BCM_ERR_OK) {
3605 OPENOLT_LOG(ERROR, openolt_log_id, "retrieval of ONU statistics failed - PON ID = %u, ONU ID = %u, err = %d - %s", intf_id, onu_id, err, bcmos_strerror(err));
3606 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of ONU statistics failed");
3607 }
3608
3609 OPENOLT_LOG(INFO, openolt_log_id, "retrieved ONU statistics for PON ID = %d, ONU ID = %d\n", (int)intf_id, (int)onu_id);
3610 return Status::OK;
3611}
3612
3613Status GetGemPortStatistics_(uint32_t intf_id, uint32_t gemport_id, openolt::GemPortStatistics* gemport_stats) {
3614 bcmos_errno err;
3615
3616 err = get_gemport_statistics((bcmolt_interface_id)intf_id, (bcmolt_gem_port_id)gemport_id, gemport_stats);
3617
3618 if (err != BCM_ERR_OK) {
3619 OPENOLT_LOG(ERROR, openolt_log_id, "retrieval of GEMPORT statistics failed - PON ID = %u, ONU ID = %u, err = %d - %s", intf_id, gemport_id, err, bcmos_strerror(err));
3620 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of GEMPORT statistics failed");
3621 }
3622
3623 OPENOLT_LOG(INFO, openolt_log_id, "retrieved GEMPORT statistics for PON ID = %d, GEMPORT ID = %d\n", (int)intf_id, (int)gemport_id);
3624 return Status::OK;
3625}
Orhan Kupusogluec57af02021-05-12 12:38:17 +00003626
Akash Reddy Kankanaladec6e7e2025-05-22 09:49:28 +05303627Status GetPonPortStatistics_(uint32_t intf_id, common::PortStatistics* pon_stats) {
3628 bcmos_errno err;
3629 bcmolt_intf_ref intf_ref;
3630 intf_ref.intf_type = BCMOLT_INTERFACE_TYPE_PON;
3631 intf_ref.intf_id = intf_id;
3632
3633 err = get_port_statistics(intf_ref, pon_stats);
3634
3635 if (err != BCM_ERR_OK) {
3636 OPENOLT_LOG(ERROR, openolt_log_id, "retrieval of Pon port statistics failed - Intf ID = %u, err = %d - %s", intf_id, err, bcmos_strerror(err));
3637 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of Pon port statistics failed");
3638 }
3639
3640 OPENOLT_LOG(INFO, openolt_log_id, "retrieved Pon port statistics for Intf ID = %d\n", (int)intf_id);
3641 return Status::OK;
3642}
3643
3644Status GetNniPortStatistics_(uint32_t intf_id, common::PortStatistics* nni_stats) {
3645 bcmos_errno err;
3646 bcmolt_intf_ref intf_ref;
3647 intf_ref.intf_type = BCMOLT_INTERFACE_TYPE_NNI;
3648 intf_ref.intf_id = intf_id;
3649
3650 err = get_port_statistics(intf_ref, nni_stats);
3651
3652 if (err != BCM_ERR_OK) {
3653 OPENOLT_LOG(ERROR, openolt_log_id, "retrieval of Nni port statistics failed - Nni Port ID = %u, err = %d - %s", intf_id, err, bcmos_strerror(err));
3654 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of Nni port statistics failed");
3655 }
3656
3657 OPENOLT_LOG(INFO, openolt_log_id, "retrieved Nni port statistics for Nni Port ID = %d\n", (int)intf_id);
3658 return Status::OK;
3659}
3660
3661Status GetAllocIdStatistics_(uint32_t intf_id, uint32_t alloc_id, openolt::OnuAllocIdStatistics* alloc_stats) {
3662 bcmos_errno err;
3663
3664 err = get_alloc_statistics((bcmolt_interface_id)intf_id, (bcmolt_alloc_id)alloc_id, alloc_stats);
3665
3666 if (err != BCM_ERR_OK) {
3667 OPENOLT_LOG(ERROR, openolt_log_id, "retrieval of ALLOC_ID statistics failed - PON ID = %u, ALLOC ID = %u, err = %d - %s", intf_id, alloc_id, err, bcmos_strerror(err));
3668 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of ALLOC_ID statistics failed");
3669 }
3670
3671 OPENOLT_LOG(INFO, openolt_log_id, "retrieved ALLOC_ID statistics for PON ID = %d, ALLOC_ID ID = %d\n", (int)intf_id, (int)alloc_id);
3672 return Status::OK;
3673}
3674
Orhan Kupusogluec57af02021-05-12 12:38:17 +00003675Status GetPonRxPower_(uint32_t intf_id, uint32_t onu_id, openolt::PonRxPowerData* response) {
3676 bcmos_errno err = BCM_ERR_OK;
3677
3678 // check the PON intf id
3679 if (intf_id >= MAX_SUPPORTED_PON) {
3680 err = BCM_ERR_PARM;
3681 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pon intf_id - intf_id: %d, onu_id: %d\n",
3682 intf_id, onu_id);
3683 return bcm_to_grpc_err(err, "invalid pon intf_id");
3684 }
3685
3686 bcmolt_onu_rssi_measurement onu_oper; /* declare main API struct */
3687 bcmolt_onu_key onu_key; /**< Object key. */
3688 onu_rssi_compltd_key key(intf_id, onu_id);
3689 Queue<onu_rssi_complete_result> queue;
3690
3691 OPENOLT_LOG(INFO, openolt_log_id, "GetPonRxPower - intf_id %d, onu_id %d\n", intf_id, onu_id);
3692
3693 onu_key.onu_id = onu_id;
3694 onu_key.pon_ni = intf_id;
3695 /* Initialize the API struct. */
3696 BCMOLT_OPER_INIT(&onu_oper, onu, rssi_measurement, onu_key);
3697 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
3698 if (err == BCM_ERR_OK) {
3699 // initialize map
3700 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3701 onu_rssi_compltd_map.insert({key, &queue});
3702 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3703 } else {
3704 OPENOLT_LOG(ERROR, openolt_log_id, "failed to measure rssi rx power - intf_id: %d, onu_id: %d, err = %s (%d): %s\n",
3705 intf_id, onu_id, bcmos_strerror(err), err, onu_oper.hdr.hdr.err_text);
3706 return bcm_to_grpc_err(err, "failed to measure rssi rx power");
3707 }
3708
3709 onu_rssi_complete_result completed{};
3710 if (!queue.pop(completed, ONU_RSSI_COMPLETE_WAIT_TIMEOUT)) {
3711 // invalidate the queue pointer
3712 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3713 onu_rssi_compltd_map[key] = NULL;
3714 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3715 err = BCM_ERR_TIMEOUT;
3716 OPENOLT_LOG(ERROR, openolt_log_id, "timeout waiting for RSSI Measurement Completed indication intf_id %d, onu_id %d\n",
3717 intf_id, onu_id);
3718 } else {
3719 OPENOLT_LOG(INFO, openolt_log_id, "RSSI Rx power - intf_id: %d, onu_id: %d, status: %s, fail_reason: %d, rx_power_mean_dbm: %f\n",
3720 completed.pon_intf_id, completed.onu_id, completed.status.c_str(), completed.reason, completed.rx_power_mean_dbm);
3721
3722 response->set_intf_id(completed.pon_intf_id);
3723 response->set_onu_id(completed.onu_id);
3724 response->set_status(completed.status);
3725 response->set_fail_reason(static_cast<::openolt::PonRxPowerData_RssiMeasurementFailReason>(completed.reason));
3726 response->set_rx_power_mean_dbm(completed.rx_power_mean_dbm);
3727 }
3728
3729 // Remove entry from map
3730 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3731 onu_rssi_compltd_map.erase(key);
3732 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3733
3734 if (err == BCM_ERR_OK) {
3735 return Status::OK;
3736 } else {
3737 return bcm_to_grpc_err(err, "timeout waiting for pon rssi measurement complete indication");
3738 }
3739}
nikesh.krishnan331d38c2023-04-06 03:24:53 +05303740
3741Status GetOnuInfo_(uint32_t intf_id, uint32_t onu_id, openolt::OnuInfo *response)
3742{
3743 bcmos_errno err = BCM_ERR_OK;
3744
3745 bcmolt_onu_state onu_state;
3746
3747 bcmolt_status losi;
3748 bcmolt_status lofi;
3749 bcmolt_status loami;
3750 err = get_gpon_onu_info((bcmolt_interface)intf_id, onu_id, &onu_state, &losi, &lofi, &loami);
3751
3752 if (err == BCM_ERR_OK)
3753 {
3754
3755 response->set_onu_id(onu_id);
3756 OPENOLT_LOG(DEBUG, openolt_log_id, "onu state %d\n", onu_state);
3757 OPENOLT_LOG(DEBUG, openolt_log_id, "losi %d\n", losi);
3758 OPENOLT_LOG(DEBUG, openolt_log_id, "lofi %d\n", lofi);
3759 OPENOLT_LOG(DEBUG, openolt_log_id, "loami %d\n", loami);
3760
3761 switch (onu_state)
3762 {
3763 case bcmolt_onu_state::BCMOLT_ONU_STATE_ACTIVE:
3764 response->set_state(openolt::OnuInfo_OnuState::OnuInfo_OnuState_ACTIVE);
3765 break;
3766 case bcmolt_onu_state::BCMOLT_ONU_STATE_INACTIVE:
3767 response->set_state(openolt::OnuInfo_OnuState::OnuInfo_OnuState_INACTIVE);
3768 break;
3769 case bcmolt_onu_state::BCMOLT_ONU_STATE_UNAWARE:
3770 response->set_state(openolt::OnuInfo_OnuState::OnuInfo_OnuState_UNKNOWN);
3771 break;
3772 case bcmolt_onu_state::BCMOLT_ONU_STATE_NOT_CONFIGURED:
3773 response->set_state(openolt::OnuInfo_OnuState::OnuInfo_OnuState_NOT_CONFIGURED);
3774 break;
3775 case bcmolt_onu_state::BCMOLT_ONU_STATE_DISABLED:
3776 response->set_state(openolt::OnuInfo_OnuState::OnuInfo_OnuState_DISABLED);
3777 break;
3778 }
3779 switch (losi)
3780 {
3781 case bcmolt_status::BCMOLT_STATUS_ON:
3782 response->set_losi(openolt::AlarmState::ON);
3783 break;
3784 case bcmolt_status::BCMOLT_STATUS_OFF:
3785 response->set_losi(openolt::AlarmState::OFF);
3786 break;
3787 }
3788
3789 switch (lofi)
3790 {
3791 case bcmolt_status::BCMOLT_STATUS_ON:
3792 response->set_lofi(openolt::AlarmState::ON);
3793 break;
3794 case bcmolt_status::BCMOLT_STATUS_OFF:
3795 response->set_lofi(openolt::AlarmState::OFF);
3796 break;
3797 }
3798
3799 switch (loami)
3800 {
3801 case bcmolt_status::BCMOLT_STATUS_ON:
3802 response->set_loami(openolt::AlarmState::ON);
3803 break;
3804 case bcmolt_status::BCMOLT_STATUS_OFF:
3805 response->set_loami(openolt::AlarmState::OFF);
3806 break;
3807 }
3808 return Status::OK;
3809 }
3810 else
3811 {
3812 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch Onu status, onu_id = %d, intf_id = %d, err = %s\n",
3813 onu_id, intf_id, bcmos_strerror(err));
3814 return bcm_to_grpc_err(err, "Failed to fetch Onu status");
3815 }
3816}
3817
3818Status GetPonInterfaceInfo_(uint32_t intf_id, openolt::PonIntfInfo *response)
3819{
3820 bcmos_errno err = BCM_ERR_OK;
3821
3822 bcmolt_status los_status;
3823 bcmolt_interface_state state;
3824 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
3825 OPENOLT_LOG(ERROR, openolt_log_id, "pon state %d\n",state);
3826 OPENOLT_LOG(ERROR, openolt_log_id, "pon los status %d\n", los_status);
3827
3828
3829 if (err == BCM_ERR_OK)
3830 {
3831 response->set_intf_id(intf_id) ;
3832 switch (los_status)
3833 {
3834 case bcmolt_status::BCMOLT_STATUS_ON:
3835
3836 response->set_los(openolt::AlarmState::ON);
3837 break;
3838 case bcmolt_status::BCMOLT_STATUS_OFF:
3839 response->set_los(openolt::AlarmState::OFF);
3840 break;
3841 }
3842
3843 switch (state)
3844 {
3845 case bcmolt_interface_state::BCMOLT_INTERFACE_STATE_ACTIVE_WORKING:
3846 response->set_state(openolt::PonIntfInfo_PonIntfState::PonIntfInfo_PonIntfState_ACTIVE_WORKING);
3847 break;
3848 case bcmolt_interface_state::BCMOLT_INTERFACE_STATE_ACTIVE_STANDBY:
3849 response->set_state(openolt::PonIntfInfo_PonIntfState::PonIntfInfo_PonIntfState_ACTIVE_STANDBY);
3850 break;
3851
3852 case bcmolt_interface_state::BCMOLT_INTERFACE_STATE_DISABLED:
3853 response->set_state(openolt::PonIntfInfo_PonIntfState::PonIntfInfo_PonIntfState_DISABLED);
3854 break;
3855
3856 case bcmolt_interface_state::BCMOLT_INTERFACE_STATE_INACTIVE:
3857
3858 response->set_state(openolt::PonIntfInfo_PonIntfState::PonIntfInfo_PonIntfState_INACTIVE);
3859 break;
3860 default:
3861 response->set_state(openolt::PonIntfInfo_PonIntfState::PonIntfInfo_PonIntfState_UNKNOWN);
3862 }
3863
3864 return Status::OK;
3865 }
3866 else
3867 {
3868 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch PON interface los status intf_id = %d, err = %s\n",
3869 intf_id, bcmos_strerror(err));
3870 return bcm_to_grpc_err(err, "Failed to fetch PON interface los status intf_id");
3871 }
3872}