blob: d8f2ae43b0e8729c4851d751e5199742d35b31b6 [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
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001141Status DisablePonIf_(uint32_t intf_id) {
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001142 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001143 bcmolt_pon_interface_cfg interface_obj;
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001144 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1145 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001146
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001147 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
Girish Gowdrae1db2952021-05-04 00:16:54 -07001148 BCMOLT_MSG_FIELD_GET(&interface_obj, state);
1149
1150 err = bcmolt_cfg_get(dev_id, &interface_obj.hdr);
1151 if (err != BCM_ERR_OK) {
1152 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);
1153 return bcm_to_grpc_err(err, "Failed to fetch pon port state");
1154 }
1155 if (interface_obj.data.state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1156 OPENOLT_LOG(INFO, openolt_log_id, "PON Interface already inactive, PON interface %d\n", intf_id);
1157 return Status::OK;
1158 }
1159
1160 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001161 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1162 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_DISABLE);
1163
1164 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1165 if (err != BCM_ERR_OK) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07001166 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 -05001167 return bcm_to_grpc_err(err, "Failed to disable discovery of onu");
1168 }
1169
1170 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1171 operation, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1172
1173 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1174 if (err != BCM_ERR_OK) {
1175 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 -04001176 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001177 }
1178
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001179 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled PON interface: %d\n", intf_id);
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001180 return Status::OK;
1181}
1182
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001183Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
kesavandc1f2db92020-08-31 15:32:06 +05301184 const char *vendor_id, const char *vendor_specific, uint32_t pir, bool omcc_encryption_mode) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001185 bcmos_errno err = BCM_ERR_OK;
1186 bcmolt_onu_cfg onu_cfg;
1187 bcmolt_onu_key onu_key;
Shivanagouda Malaginahallie707d612023-08-22 10:40:25 +00001188 bcmolt_serial_number serial_number = {}; /**< ONU serial number */
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001189 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001190
Girish Gowdra24297032020-03-23 12:32:37 -07001191 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1192 bcmolt_onu_state onu_state;
1193
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001194 onu_key.onu_id = onu_id;
1195 onu_key.pon_ni = intf_id;
1196 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1197 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Girish Gowdra24297032020-03-23 12:32:37 -07001198#ifdef TEST_MODE
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001199 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1200 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1201 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1202 // of onu_cfg is passed. This is one-of case where we need to add test specific
1203 // code in production code.
1204 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Girish Gowdra24297032020-03-23 12:32:37 -07001205#else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001206 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Girish Gowdra24297032020-03-23 12:32:37 -07001207#endif
1208 OPENOLT_LOG(INFO, openolt_log_id, "Activate ONU : old state = %d, current state = %d\n",
1209 onu_cfg.data.onu_old_state, onu_cfg.data.onu_state);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001210 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001211 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) {
1212 OPENOLT_LOG(INFO, openolt_log_id, "ONU is already in ACTIVE state, \
1213not processing this request for pon_intf=%d onu_id=%d\n", intf_id, onu_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001214 return Status::OK;
Girish Gowdra24297032020-03-23 12:32:37 -07001215 } else if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_NOT_CONFIGURED &&
1216 onu_cfg.data.onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1217 // We need the ONU to be in NOT_CONFIGURED or INACTIVE state to further process the request
1218 OPENOLT_LOG(ERROR, openolt_log_id, "ONU in an invalid state to process the request, \
1219state=%d pon_intf=%d onu_id=%d\n", onu_cfg.data.onu_state, intf_id, onu_id);
1220 return bcm_to_grpc_err(err, "Failed to activate ONU, invalid ONU state");
1221 }
1222 } else {
1223 // This should never happen. BAL GET should succeed for non-existant ONUs too. The state of such ONUs will be NOT_CONFIGURED
1224 OPENOLT_LOG(ERROR, openolt_log_id, "ONU state query failed pon_intf=%d onu_id=%d\n", intf_id, onu_id);
1225 return bcm_to_grpc_err(err, "onu get failed");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001226 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001227
Girish Gowdra24297032020-03-23 12:32:37 -07001228 // If the ONU is not configured at all we need to first configure it
1229 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_NOT_CONFIGURED) {
1230 OPENOLT_LOG(INFO, openolt_log_id, "Configuring ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001231vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Girish Gowdra24297032020-03-23 12:32:37 -07001232 vendor_specific_to_str(vendor_specific).c_str(), pir);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001233
Girish Gowdra24297032020-03-23 12:32:37 -07001234 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1235 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
Shivanagouda Malaginahallie707d612023-08-22 10:40:25 +00001236
Girish Gowdra24297032020-03-23 12:32:37 -07001237 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1238 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1239 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1240 /*set burst and data profiles to fec disabled*/
Arthur Syu094df162022-04-21 17:50:06 +08001241 std::string intf_technology = intf_technologies[intf_id];
1242 if (intf_technology == "XGS-PON") {
Girish Gowdra24297032020-03-23 12:32:37 -07001243 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1244 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
Arthur Syu094df162022-04-21 17:50:06 +08001245 } else if (intf_technology == "GPON") {
Girish Gowdra24297032020-03-23 12:32:37 -07001246 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1247 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1248 }
1249 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1250 if (err != BCM_ERR_OK) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07001251 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 -07001252 return bcm_to_grpc_err(err, "Failed to configure ONU");
1253 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001254 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001255
Burak Gurdaga0523592021-02-24 15:17:47 +00001256// TODO: MOVE THIS TO A NEW METHOD
kesavandc1f2db92020-08-31 15:32:06 +05301257 if (omcc_encryption_mode == true) {
1258 // set the encryption mode for omci port id
1259 bcmolt_itupon_gem_cfg gem_cfg;
1260 bcmolt_itupon_gem_key key = {};
1261 bcmolt_gem_port_configuration configuration = {};
1262 key.pon_ni = intf_id;
1263 key.gem_port_id = onu_id;
1264 bcmolt_control_state encryption_mode;
1265 encryption_mode = BCMOLT_CONTROL_STATE_ENABLE;
1266 BCMOLT_CFG_INIT(&gem_cfg, itupon_gem, key);
1267 BCMOLT_FIELD_SET(&gem_cfg.data, itupon_gem_cfg_data, encryption_mode, encryption_mode);
1268 err = bcmolt_cfg_set(dev_id, &gem_cfg.hdr);
1269 if(err != BCM_ERR_OK) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07001270 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 +05301271 return bcm_to_grpc_err(err, "Access_Control set ITU PON OMCI Gem port failed");
1272 }
1273 }
Girish Gowdra24297032020-03-23 12:32:37 -07001274 // Now that the ONU is configured, move the ONU to ACTIVE state
1275 memset(&onu_cfg, 0, sizeof(bcmolt_onu_cfg));
1276 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1277 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1278 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
1279 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
1280 onu_state, BCMOLT_ONU_OPERATION_ACTIVE);
1281 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001282 if (err != BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001283 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 +00001284 return bcm_to_grpc_err(err, "Failed to activate ONU");
1285 }
Girish Gowdra24297032020-03-23 12:32:37 -07001286 // ONU will eventually get activated after we have submitted the operation request. The adapter will receive an asynchronous
1287 // ONU_ACTIVATION_COMPLETED_INDICATION
1288
1289 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 +00001290
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001291 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001292}
1293
Jonathan Davis70c21812018-07-19 15:32:10 -04001294Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1295 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001296 bcmos_errno err = BCM_ERR_OK;
1297 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1298 bcmolt_onu_cfg onu_cfg;
1299 bcmolt_onu_key onu_key; /**< Object key. */
1300 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001301
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001302 onu_key.onu_id = onu_id;
1303 onu_key.pon_ni = intf_id;
1304 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1305 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1306 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301307 onu_state = onu_cfg.data.onu_state;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001308 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001309 switch (onu_state) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001310 case BCMOLT_ONU_STATE_ACTIVE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001311 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001312 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001313 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1314 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1315 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001316 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 +00001317 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1318 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301319 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 +00001320 break;
1321 }
Girish Gowdra72cbee92021-11-05 15:16:18 -07001322 } else {
1323 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to deactivate ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
1324 return bcm_to_grpc_err(err, "Failed to get onu config");
Jonathan Davis70c21812018-07-19 15:32:10 -04001325 }
1326
1327 return Status::OK;
1328}
1329
1330Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001331 const char *vendor_id, const char *vendor_specific) {
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301332 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301333 bcmolt_onu_state onu_state;
Girish Gowdra72cbee92021-11-05 15:16:18 -07001334 Status st;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001335
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001336 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 -05001337 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1338
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001339 // Need to deactivate before removing it (BAL rules)
Girish Gowdra72cbee92021-11-05 15:16:18 -07001340 st = DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
1341 if (st.error_code() != grpc::StatusCode::OK) {
1342 return st;
1343 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301344
Girish Gowdra72cbee92021-11-05 15:16:18 -07001345 err = get_onu_state((bcmolt_interface)intf_id, onu_id, &onu_state);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301346 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001347 if (onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1348 OPENOLT_LOG(INFO, openolt_log_id, "waiting for onu deactivate complete response: intf_id=%d, onu_id=%d\n",
1349 intf_id, onu_id);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301350 err = wait_for_onu_deactivate_complete(intf_id, onu_id);
1351 if (err) {
1352 OPENOLT_LOG(ERROR, openolt_log_id, "failed to delete onu intf_id %d, onu_id %d\n",
1353 intf_id, onu_id);
1354 return bcm_to_grpc_err(err, "Failed to delete ONU");
1355 }
1356 }
Girish Gowdra24297032020-03-23 12:32:37 -07001357 else {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301358 OPENOLT_LOG(INFO, openolt_log_id, "Onu is Inactive, onu_id: %d, not waiting for onu deactivate complete response\n",
1359 intf_id);
1360 }
1361 }
1362 else {
1363 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch Onu status, onu_id = %d, intf_id = %d, err = %s\n",
1364 onu_id, intf_id, bcmos_strerror(err));
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301365 return bcm_to_grpc_err(err, "Failed to delete ONU");
1366 }
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001367
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001368 bcmolt_onu_cfg cfg_obj;
1369 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001370
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001371 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 -04001372 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001373
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001374 key.onu_id = onu_id;
1375 key.pon_ni = intf_id;
1376 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001377
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301378 err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001379 if (err != BCM_ERR_OK)
1380 {
Girish Gowdra72cbee92021-11-05 15:16:18 -07001381 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 -04001382 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1383 }
1384
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301385 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 +00001386 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001387}
1388
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001389#define MAX_CHAR_LENGTH 20
1390#define MAX_OMCI_MSG_LENGTH 44
1391Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001392 bcmolt_bin_str buf = {};
1393 bcmolt_onu_cpu_packets omci_cpu_packets;
1394 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001395
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001396 key.pon_ni = intf_id;
1397 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001398
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001399 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1400 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1401 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001402
1403 // ???
1404 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1405 buf.len = MAX_OMCI_MSG_LENGTH;
1406 } else {
1407 buf.len = pkt.size()/2;
1408 }
1409
1410 /* Send the OMCI packet using the BAL remote proxy API */
1411 uint16_t idx1 = 0;
1412 uint16_t idx2 = 0;
1413 uint8_t arraySend[buf.len];
1414 char str1[MAX_CHAR_LENGTH];
1415 char str2[MAX_CHAR_LENGTH];
1416 memset(&arraySend, 0, buf.len);
1417
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001418 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1419 sprintf(str1,"%c", pkt[idx1]);
1420 sprintf(str2,"%c", pkt[++idx1]);
1421 strcat(str1,str2);
1422 arraySend[idx2] = strtol(str1, NULL, 16);
1423 }
1424
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001425 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1426 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001427
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001428 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1429 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1430 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001431
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001432 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001433 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001434 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 +00001435 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001436 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001437 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 -05001438 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001439 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001440 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001441
1442 return Status::OK;
1443}
1444
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001445Status 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 +00001446 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1447 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1448 bcmolt_bin_str buf = {};
1449 bcmolt_gem_port_id gem_port_id_array[1];
1450 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001451
Craig Lutgen967a1d02018-11-27 10:41:51 -06001452 if (port_no > 0) {
1453 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001454 if (gemport_id == 0) {
1455 bcmos_fastlock_lock(&data_lock);
1456 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1457 // Pick any flow that is mapped with the same port_no.
1458 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1459 if (it != port_to_flows.end() && !it->second.empty()) {
1460 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1461 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1462 if (fit != flowid_to_gemport.end()) {
1463 found = true;
1464 gemport_id = fit->second;
1465 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001466 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001467 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001468
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001469 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001470 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 -08001471 onu_id, port_no, intf_id);
1472 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1473 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001474 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 -08001475 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001476 }
1477
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001478 gem_port_id_array[0] = gemport_id;
1479 gem_port_list.len = 1;
1480 gem_port_list.arr = gem_port_id_array;
1481 buf.len = pkt.size();
1482 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1483 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1484
1485 /* init the API struct */
1486 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1487 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1488 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1489 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1490 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1491
1492 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1493 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1494
1495 /* call API */
1496 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001497 }
1498 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001499 //TODO: Port No is 0, it is coming sender requirement.
1500 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1501 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001502 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001503 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001504
1505 return Status::OK;
1506}
1507
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001508Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001509 bcmolt_flow_key key = {}; /* declare key */
1510 bcmolt_bin_str buffer = {};
1511 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001512
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001513 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
Girish Gowdra252f4972020-09-07 21:24:01 -07001514 bcmolt_flow_id flow_id = INVALID_FLOW_ID;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001515
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001516 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1517 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1518 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1519 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1520 key.flow_id = flow_id;
1521 else {
Jason Huang09b73ea2020-01-08 17:52:05 +08001522 if (flow_id_counters) {
1523 std::map<flow_pair, int>::iterator it;
1524 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1525 int flow_index = it->first.first;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001526 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1527 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1528 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1529 key.flow_id = flow_index;
1530 break;
1531 }
1532 }
1533 }
1534 else {
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001535 OPENOLT_LOG(ERROR, openolt_log_id, "no flow id found for uplink packetout\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001536 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1537 }
1538 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001539
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001540 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001541
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001542 /* Initialize the API struct. */
1543 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001544
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001545 buffer.len = pkt.size();
1546 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1547 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1548 if (buffer.arr == NULL) {
1549 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1550 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1551 }
1552 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1553
1554 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1555 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001556 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 -05001557 return bcm_to_grpc_err(BCM_ERR_SYSCALL_ERR, "Error sending packets via nni port");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001558 } else {
1559 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1560 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001561
1562 return Status::OK;
1563}
Girish Gowdra252f4972020-09-07 21:24:01 -07001564
Burak Gurdaga0523592021-02-24 15:17:47 +00001565bool get_aes_flag_for_gem_port(const google::protobuf::Map<unsigned int, bool> &gemport_to_aes, uint32_t gemport_id) {
1566 bool aes_flag = false;
1567 for (google::protobuf::Map<unsigned int, bool>::const_iterator it=gemport_to_aes.begin(); it!=gemport_to_aes.end(); it++) {
1568 if (it->first == gemport_id) {
1569 aes_flag = it->second;
1570 break;
1571 }
1572 }
1573 return aes_flag;
1574}
1575
Girish Gowdra252f4972020-09-07 21:24:01 -07001576Status FlowAddWrapper_(const ::openolt::Flow* request) {
1577
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001578 Status st = Status::OK;
Girish Gowdra252f4972020-09-07 21:24:01 -07001579 int32_t access_intf_id = request->access_intf_id();
1580 int32_t onu_id = request->onu_id();
1581 int32_t uni_id = request->uni_id();
1582 uint32_t port_no = request->port_no();
1583 uint64_t voltha_flow_id = request->flow_id();
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001584 uint64_t symmetric_voltha_flow_id = 0;
Girish Gowdra252f4972020-09-07 21:24:01 -07001585 const std::string flow_type = request->flow_type();
1586 int32_t alloc_id = request->alloc_id();
1587 int32_t network_intf_id = request->network_intf_id();
1588 int32_t gemport_id = request->gemport_id();
1589 const ::openolt::Classifier& classifier = request->classifier();
1590 const ::openolt::Action& action = request->action();
1591 int32_t priority = request->priority();
1592 uint64_t cookie = request->cookie();
1593 int32_t group_id = request->group_id();
1594 uint32_t tech_profile_id = request->tech_profile_id();
1595 bool replicate_flow = request->replicate_flow();
1596 const google::protobuf::Map<unsigned int, unsigned int> &pbit_to_gemport = request->pbit_to_gemport();
Burak Gurdaga0523592021-02-24 15:17:47 +00001597 const google::protobuf::Map<unsigned int, bool> &gemport_to_aes = request->gemport_to_aes();
Girish Gowdra252f4972020-09-07 21:24:01 -07001598 uint16_t flow_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001599 bool enable_encryption;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001600 // When following conditions are ALL met, it qualifies as datapath flow.
1601 // 1. valid access_intf_id, onu_id, uni_id
1602 // 2. Valid tech_profile_id
1603 // 3. flow_type that is not MULTICAST
1604 // 4. Not a trap-to-host flow.
1605 bool datapathFlow = access_intf_id >= 0 && onu_id >= 0 && uni_id >= 0 && tech_profile_id > 0
1606 && flow_type != multicast && !action.cmd().trap_to_host();
1607
1608 if (datapathFlow) {
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08001609 const std::string inverse_flow_type = flow_type == upstream? downstream : upstream;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001610 symmetric_datapath_flow_id_map_key key(access_intf_id, onu_id, uni_id, tech_profile_id, inverse_flow_type);
1611 // Find the onu-uni mapping for the pon-gem key
1612 bcmos_fastlock_lock(&symmetric_datapath_flow_id_lock);
1613 auto it = symmetric_datapath_flow_id_map.find(key);
1614 bcmos_fastlock_unlock(&symmetric_datapath_flow_id_lock, 0);
1615 if (it != symmetric_datapath_flow_id_map.end()) {
1616 symmetric_voltha_flow_id = it->second;
1617 }
1618 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001619
1620 // The intf_id variable defaults to access(PON) interface ID.
1621 // For trap-from-nni flow where access interface ID is not valid , change it to NNI interface ID
1622 // This intf_id identifies the pool from which we get the flow_id
1623 uint32_t intf_id = access_intf_id;
1624 if (onu_id < 1) {
1625 onu_id = 1;
1626 }
1627 if (access_intf_id < 0) {
1628 intf_id = network_intf_id;
1629 }
1630
Sridhar Ravindra57d7eb92025-06-04 13:39:43 +05301631 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 -07001632 // This is the case of voltha_flow_id (not symmetric_voltha_flow_id)
1633 if (is_voltha_flow_installed(voltha_flow_id)) {
1634 OPENOLT_LOG(INFO, openolt_log_id, "voltha_flow_id=%lu, already installed\n", voltha_flow_id);
1635 return ::Status(grpc::StatusCode::ALREADY_EXISTS, "voltha-flow-already-installed");
1636 }
1637
Girish Gowdra252f4972020-09-07 21:24:01 -07001638 // This is the case of symmetric_voltha_flow_id
1639 // If symmetric_voltha_flow_id is available and valid in the Flow message,
1640 // check if it is installed, and use the corresponding device_flow_id
1641 if (symmetric_voltha_flow_id > 0 && is_voltha_flow_installed(symmetric_voltha_flow_id)) { // symmetric flow found
1642 OPENOLT_LOG(INFO, openolt_log_id, "symmetric flow and the symmetric flow is installed\n");
1643 const device_flow_params *dev_fl_symm_params;
1644 dev_fl_symm_params = get_device_flow_params(symmetric_voltha_flow_id);
1645 if (dev_fl_symm_params == NULL) {
1646 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)
1647 return ::Status(grpc::StatusCode::INTERNAL, "symmetric-flow-details-not-found");
1648 }
1649
1650 if (!replicate_flow) { // No flow replication
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001651 flow_id = dev_fl_symm_params[0].flow_id;
1652 gemport_id = dev_fl_symm_params[0].gemport_id; // overwrite the gemport with symmetric flow gemport
1653 // Should be same as what is coming in this request.
1654 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
1655 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1656 cl.set_o_pbits(dev_fl_symm_params[0].pbit);
1657 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1658 flow_type, alloc_id, network_intf_id, gemport_id, cl,
1659 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
1660 if (st.error_code() != grpc::StatusCode::OK && st.error_code() != grpc::StatusCode::ALREADY_EXISTS) {
1661 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 -07001662 free_flow_id(flow_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001663 return st;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001664 }
1665
1666 device_flow dev_fl;
1667 dev_fl.is_flow_replicated = false;
1668 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1669 dev_fl.voltha_flow_id = voltha_flow_id;
Girish Gowdra72bb4652022-01-18 17:04:30 -08001670 dev_fl.flow_type = flow_type;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001671 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params));
1672 // update voltha flow to cache
1673 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
Girish Gowdra252f4972020-09-07 21:24:01 -07001674 } else { // Flow to be replicated
1675 OPENOLT_LOG(INFO, openolt_log_id,"symmetric flow and replication is needed\n");
Girish Gowdra52997cc2022-06-02 20:58:50 -07001676 if (pbit_to_gemport.size() > NUMBER_OF_PBITS) {
1677 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pbit-to-gemport map size=%lu", pbit_to_gemport.size())
1678 return ::Status(grpc::StatusCode::OUT_OF_RANGE, "pbit-to-gemport-map-len-invalid-for-flow-replication");
1679 }
1680 for (uint8_t i=0; i<pbit_to_gemport.size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07001681 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1682 flow_id = dev_fl_symm_params[i].flow_id;
1683 gemport_id = dev_fl_symm_params[i].gemport_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001684 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001685 cl.set_o_pbits(dev_fl_symm_params[i].pbit);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001686 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdrade65ab42020-12-17 23:08:43 -08001687 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001688 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001689 if (st.error_code() != grpc::StatusCode::OK && st.error_code() != grpc::StatusCode::ALREADY_EXISTS) {
1690 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);
1691 // On failure remove any successfully replicated flows installed so far for the voltha_flow_id
1692 if (i > 0) {
1693 for (int8_t j = i-1; j >= 0; j--) {
1694 flow_id = dev_fl_symm_params[j].flow_id;
1695 FlowRemove_(flow_id, flow_type);
1696 }
1697 }
Girish Gowdra72cbee92021-11-05 15:16:18 -07001698 // Note: We should not free the flow_ids here because the symmetric flow is already using that flow id.
1699 // 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 -07001700 return st;
1701 }
1702 }
1703 device_flow dev_fl;
1704 dev_fl.is_flow_replicated = true;
1705 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1706 dev_fl.voltha_flow_id = voltha_flow_id;
Girish Gowdra52997cc2022-06-02 20:58:50 -07001707 dev_fl.total_replicated_flows = pbit_to_gemport.size();
Girish Gowdra72bb4652022-01-18 17:04:30 -08001708 dev_fl.flow_type = flow_type;
Girish Gowdra52997cc2022-06-02 20:58:50 -07001709 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params)*dev_fl.total_replicated_flows);
Girish Gowdra252f4972020-09-07 21:24:01 -07001710 // update voltha flow to cache
1711 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1712 }
1713 } else { // No symmetric flow found
1714 if (!replicate_flow) { // No flow replication
1715 OPENOLT_LOG(INFO, openolt_log_id, "not a symmetric flow and replication is not needed\n");
1716 flow_id = get_flow_id();
1717 if (flow_id == INVALID_FLOW_ID) {
1718 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocated flow id for voltha-flow-id=%lu\n", voltha_flow_id);
1719 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1720 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001721 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001722 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001723 flow_type, alloc_id, network_intf_id, gemport_id, classifier,
Burak Gurdaga0523592021-02-24 15:17:47 +00001724 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001725 if (st.error_code() == grpc::StatusCode::OK) {
1726 device_flow dev_fl;
1727 dev_fl.is_flow_replicated = false;
1728 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // Invalid
1729 dev_fl.voltha_flow_id = voltha_flow_id;
Girish Gowdra72bb4652022-01-18 17:04:30 -08001730 dev_fl.flow_type = flow_type;
Girish Gowdra252f4972020-09-07 21:24:01 -07001731 dev_fl.params[0].flow_id = flow_id;
1732 dev_fl.params[0].gemport_id = gemport_id;
1733 dev_fl.params[0].pbit = classifier.o_pbits();
1734 // update voltha flow to cache
1735 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1736 } else {
1737 // Free the flow id on failure
1738 free_flow_id(flow_id);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001739 return st;
Girish Gowdra252f4972020-09-07 21:24:01 -07001740 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001741 } else { // Flow to be replicated
1742 OPENOLT_LOG(INFO, openolt_log_id,"not a symmetric flow and replication is needed\n");
Girish Gowdra52997cc2022-06-02 20:58:50 -07001743 if (pbit_to_gemport.size() > NUMBER_OF_PBITS) {
Girish Gowdra252f4972020-09-07 21:24:01 -07001744 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pbit-to-gemport map size=%lu", pbit_to_gemport.size())
1745 return ::Status(grpc::StatusCode::OUT_OF_RANGE, "pbit-to-gemport-map-len-invalid-for-flow-replication");
1746 }
Girish Gowdra52997cc2022-06-02 20:58:50 -07001747 uint16_t flow_ids[MAX_NUMBER_OF_REPLICATED_FLOWS];
Girish Gowdra252f4972020-09-07 21:24:01 -07001748 device_flow dev_fl;
Girish Gowdra52997cc2022-06-02 20:58:50 -07001749 if (get_flow_ids(pbit_to_gemport.size(), flow_ids)) {
Girish Gowdra252f4972020-09-07 21:24:01 -07001750 uint8_t cnt = 0;
1751 dev_fl.is_flow_replicated = true;
1752 dev_fl.voltha_flow_id = voltha_flow_id;
1753 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // invalid
Girish Gowdra52997cc2022-06-02 20:58:50 -07001754 dev_fl.total_replicated_flows = pbit_to_gemport.size();
Girish Gowdra72bb4652022-01-18 17:04:30 -08001755 dev_fl.flow_type = flow_type;
Girish Gowdra252f4972020-09-07 21:24:01 -07001756 for (google::protobuf::Map<unsigned int, unsigned int>::const_iterator it=pbit_to_gemport.begin(); it!=pbit_to_gemport.end(); it++) {
1757 dev_fl.params[cnt].flow_id = flow_ids[cnt];
1758 dev_fl.params[cnt].pbit = it->first;
1759 dev_fl.params[cnt].gemport_id = it->second;
1760
1761 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1762 flow_id = dev_fl.params[cnt].flow_id;
1763 gemport_id = dev_fl.params[cnt].gemport_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001764 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001765 cl.set_o_pbits(dev_fl.params[cnt].pbit);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001766 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001767 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001768 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001769 if (st.error_code() != grpc::StatusCode::OK) {
1770 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);
1771 // Remove any successfully replicated flows installed so far for the voltha_flow_id
1772 if (cnt > 0) {
1773 for (int8_t j = cnt-1; j >= 0; j--) {
1774 flow_id = dev_fl.params[j].flow_id;
1775 FlowRemove_(flow_id, flow_type);
1776 }
1777 }
1778 // Free up all the flow IDs on failure
Girish Gowdra52997cc2022-06-02 20:58:50 -07001779 free_flow_ids(pbit_to_gemport.size(), flow_ids);
Girish Gowdra252f4972020-09-07 21:24:01 -07001780 return st;
1781 }
1782 cnt++;
1783 }
1784 // On successful flow replication update voltha-flow-id to device-flow map to cache
1785 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1786 } else {
1787 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocate flow ids for replication voltha-flow-id=%lu\n", voltha_flow_id);
1788 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1789 }
1790 }
1791 }
1792
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001793 if (datapathFlow) {
1794 // Create the pon-gem to onu-uni mapping
1795 symmetric_datapath_flow_id_map_key key(access_intf_id, onu_id, uni_id, tech_profile_id, flow_type);
1796 bcmos_fastlock_lock(&symmetric_datapath_flow_id_lock);
1797 symmetric_datapath_flow_id_map[key] = voltha_flow_id;
1798 bcmos_fastlock_unlock(&symmetric_datapath_flow_id_lock, 0);
1799 }
1800
1801 return st;
Girish Gowdra252f4972020-09-07 21:24:01 -07001802}
1803
1804
Craig Lutgen967a1d02018-11-27 10:41:51 -06001805Status 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 +00001806 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001807 int32_t alloc_id, int32_t network_intf_id,
1808 int32_t gemport_id, const ::openolt::Classifier& classifier,
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001809 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie,
Burak Gurdaga0523592021-02-24 15:17:47 +00001810 int32_t group_id, uint32_t tech_profile_id, bool aes_enabled) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001811 bcmolt_flow_cfg cfg;
1812 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001813 int32_t o_vid = -1;
1814 bool single_tag = false;
1815 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001816 bcmolt_classifier c_val = { };
1817 bcmolt_action a_val = { };
1818 bcmolt_tm_queue_ref tm_val = { };
1819 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05001820 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001821
Jason Huang09b73ea2020-01-08 17:52:05 +08001822 OPENOLT_LOG(INFO, openolt_log_id, "flow add received for flow_id=%u, flow_type=%s\n", flow_id, flow_type.c_str());
1823
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001824 key.flow_id = flow_id;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08001825 if (flow_type == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001826 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08001827 } else if (flow_type == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001828 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08001829 } else if (flow_type == multicast) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001830 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001831 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001832 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001833 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001834 }
1835
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001836 BCMOLT_CFG_INIT(&cfg, flow, key);
1837 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001838
Jason Huang09b73ea2020-01-08 17:52:05 +08001839 if (action.cmd().trap_to_host()) {
Girish Gowdra1935e6a2020-10-31 21:48:22 -07001840 Status resp = handle_acl_rule_install(onu_id, flow_id, gemport_id, flow_type, access_intf_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001841 network_intf_id, classifier);
Jason Huang09b73ea2020-01-08 17:52:05 +08001842 return resp;
1843 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001844
1845 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1846
1847 if (access_intf_id >= 0 && network_intf_id >= 0) {
1848 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1849 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1850 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08001851 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1852 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001853 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1854 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1855 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1856 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1857 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001858 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001859 } else {
1860 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
1861 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001862 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001863
Burak Gurdaga0523592021-02-24 15:17:47 +00001864 if (onu_id >= ONU_ID_START) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001865 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
1866 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001867 if (gemport_id >= GEM_PORT_ID_START) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001868 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
1869 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001870 if (gemport_id >= GEM_PORT_ID_START && port_no != 0) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001871 bcmos_fastlock_lock(&data_lock);
1872 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
1873 port_to_flows[port_no].insert(key.flow_id);
1874 flowid_to_gemport[key.flow_id] = gemport_id;
1875 }
1876 else
1877 {
1878 flowid_to_port[key.flow_id] = port_no;
1879 }
1880 bcmos_fastlock_unlock(&data_lock, 0);
1881 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001882
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001883 if (priority_value >= 0) {
1884 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
1885 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301886
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001887 } else { // MULTICAST FLOW
1888 if (group_id >= 0) {
1889 BCMOLT_MSG_FIELD_SET(&cfg, group_id, group_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001890 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001891 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1892 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001893 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001894
1895 {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001896 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001897 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001898 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
1899 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001900 }
1901
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001902 if (classifier.dst_mac().size() > 0) {
1903 bcmos_mac_address d_mac = {};
1904 bcmos_mac_address_init(&d_mac);
1905 memcpy(d_mac.u8, classifier.dst_mac().data(), sizeof(d_mac.u8));
1906 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_mac %02x:%02x:%02x:%02x:%02x:%02x\n", d_mac.u8[0],
1907 d_mac.u8[1], d_mac.u8[2], d_mac.u8[3], d_mac.u8[4], d_mac.u8[5]);
1908 BCMOLT_FIELD_SET(&c_val, classifier, dst_mac, d_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001909 }
1910
Girish Gowdraf83e17a2022-02-16 16:27:00 -08001911 if (classifier.src_mac().size() > 0) {
1912 bcmos_mac_address s_mac = {};
1913 bcmos_mac_address_init(&s_mac);
1914 memcpy(s_mac.u8, classifier.src_mac().data(), sizeof(s_mac.u8));
1915 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_mac %02x:%02x:%02x:%02x:%02x:%02x\n", s_mac.u8[0],
1916 s_mac.u8[1], s_mac.u8[2], s_mac.u8[3], s_mac.u8[4], s_mac.u8[5]);
1917 BCMOLT_FIELD_SET(&c_val, classifier, src_mac, s_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001918 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001919
1920 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001921 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
1922 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001923 }
1924
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001925 if (classifier.dst_ip()) {
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08001926 bcmos_ipv4_address d_ip = {};
1927 bcmos_ipv4_address_init(&d_ip);
1928 d_ip.u32 = classifier.dst_ip();
1929 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_ip %04x\n", d_ip.u32);
1930 BCMOLT_FIELD_SET(&c_val, classifier, dst_ip, d_ip);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001931 }
1932
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08001933 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001934 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001935 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001936 }
1937 */
1938
1939 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001940 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
1941 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001942 }
1943
1944 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001945 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
1946 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001947 }
1948
1949 if (!classifier.pkt_tag_type().empty()) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001950 if (classifier.o_vid()) {
1951 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
1952 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
1953 }
1954
1955 if (classifier.i_vid()) {
1956 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
1957 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
1958 }
1959
1960 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
1961 if (classifier.pkt_tag_type().compare("untagged") == 0) {
1962 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
1963 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
1964 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
1965 single_tag = true;
1966
1967 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301968 // OpenOlt adapter will send 0xFF in case of no pbit classification
1969 // If it is any other value (0 to 7), it is for outer pbit classification.
1970 // OpenFlow protocol does not provide inner pbit classification (in case of double tagged packets),
1971 // and VOLTHA has not used any workaround to solve this problem (for ex: use metadata field).
1972 // Also there exists no use case for i-pbit classification, so we can safely ignore this for now.
1973 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001974 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301975 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001976 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
1977 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001978
Jason Huang09b73ea2020-01-08 17:52:05 +08001979 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301980 // Same comments as in case of "single_tag" packets.
1981 // 0xFF means no pbit classification, otherwise a valid PCP (0 to 7).
1982 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001983 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301984 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001985 }
1986 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001987 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001988 }
1989
Jason Huang09b73ea2020-01-08 17:52:05 +08001990 const ::openolt::ActionCmd& cmd = action.cmd();
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001991
Jason Huang09b73ea2020-01-08 17:52:05 +08001992 if (cmd.add_outer_tag()) {
1993 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
1994 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001995 }
1996
Jason Huang09b73ea2020-01-08 17:52:05 +08001997 if (cmd.remove_outer_tag()) {
1998 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
1999 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
2000 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05302001
Girish Gowdraf83e17a2022-02-16 16:27:00 -08002002 if (cmd.translate_outer_tag()) {
2003 OPENOLT_LOG(DEBUG, openolt_log_id, "action translate o_tag\n");
2004 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_XLATE_OUTER_TAG);
2005 }
2006
Jason Huang09b73ea2020-01-08 17:52:05 +08002007 if (action.o_vid()) {
2008 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
2009 o_vid = action.o_vid();
2010 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
2011 }
2012
2013 if (action.o_pbits()) {
2014 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
2015 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
2016 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05302017
Jason Huang09b73ea2020-01-08 17:52:05 +08002018 if (action.i_vid()) {
2019 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
2020 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
2021 }
2022
2023 if (action.i_pbits()) {
2024 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
2025 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
2026 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05302027
Jason Huang09b73ea2020-01-08 17:52:05 +08002028 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
2029
Burak Gurdaga0523592021-02-24 15:17:47 +00002030 if ((access_intf_id >= 0) && (onu_id >= ONU_ID_START)) {
Jason Huang09b73ea2020-01-08 17:52:05 +08002031 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
2032 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002033 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 +00002034
Jason Huang09b73ea2020-01-08 17:52:05 +08002035 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2036 // Queue 0 on DS subscriber scheduler
2037 tm_val.queue_id = 0;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002038
Jason Huang09b73ea2020-01-08 17:52:05 +08002039 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2040 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2041 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002042
Jason Huang09b73ea2020-01-08 17:52:05 +08002043 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2044 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2045 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002046
Jason Huang09b73ea2020-01-08 17:52:05 +08002047 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2048 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
2049 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 +00002050
Jason Huang09b73ea2020-01-08 17:52:05 +08002051 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2052 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2053 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2054 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 +00002055
Jason Huang09b73ea2020-01-08 17:52:05 +08002056 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2057 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2058 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2059 }
2060 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
2061 // NNI Scheduler ID
2062 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2063 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2064 // Queue 0 on NNI scheduler
2065 tm_val.queue_id = 0;
2066 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2067 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2068 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002069
Jason Huang09b73ea2020-01-08 17:52:05 +08002070 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 +00002071 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2072 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2073
Jason Huang09b73ea2020-01-08 17:52:05 +08002074 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2075 /* Fetch TM QMP ID mapped to US NNI scheduler */
2076 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2077 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2078 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2079 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2080 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 +00002081
Sridhar Ravindra57d7eb92025-06-04 13:39:43 +05302082 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, tm_qmp_id = %d, sched_id = %d, intf_type %s\n", \
2083 upstream.c_str(), tm_q_set_id, tm_qmp_id, tm_val.sched_id, \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002084 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002085 }
Shad Ansari39739bc2018-09-13 21:38:37 +00002086 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302087 } else {
2088 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2089 tm_val.queue_id = 0;
2090
2091 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2092 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2093 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2094
2095 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2096 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
2097 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00002098 }
2099
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002100 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002101
Girish Gowdra252f4972020-09-07 21:24:01 -07002102#ifndef SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002103 // BAL 3.1 supports statistics only for unicast flows.
2104 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
2105 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
2106 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002107#endif // SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002108
Girish Gowdra252f4972020-09-07 21:24:01 -07002109#ifndef SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002110#ifdef FLOW_CHECKER
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002111 //Flow Checker, To avoid duplicate flow.
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002112 if (flow_id_counters != 0) {
2113 bool b_duplicate_flow = false;
Jason Huang09b73ea2020-01-08 17:52:05 +08002114 std::map<flow_pair, int>::iterator it;
2115
2116 for(it = flow_map.begin(); it != flow_map.end(); it++) {
2117 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(it->first.first, it->first.second, ONU_ID)) && \
2118 (key.flow_type == it->first.second) && \
2119 (cfg.data.svc_port_id == get_flow_status(it->first.first, it->first.second, SVC_PORT_ID)) && \
2120 (cfg.data.priority == get_flow_status(it->first.first, it->first.second, PRIORITY)) && \
2121 (cfg.data.cookie == get_flow_status(it->first.first, it->first.second, COOKIE)) && \
2122 (cfg.data.ingress_intf.intf_type == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_TYPE)) && \
2123 (cfg.data.ingress_intf.intf_id == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_ID)) && \
2124 (cfg.data.egress_intf.intf_type == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_TYPE)) && \
2125 (cfg.data.egress_intf.intf_id == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_ID)) && \
2126 (c_val.o_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_VID)) && \
2127 (c_val.o_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_PBITS)) && \
2128 (c_val.i_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_VID)) && \
2129 (c_val.i_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_PBITS)) && \
2130 (c_val.ether_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_ETHER_TYPE)) && \
2131 (c_val.ip_proto == get_flow_status(it->first.first, it->first.second, CLASSIFIER_IP_PROTO)) && \
2132 (c_val.src_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_SRC_PORT)) && \
2133 (c_val.dst_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_DST_PORT)) && \
2134 (c_val.pkt_tag_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_PKT_TAG_TYPE)) && \
2135 (cfg.data.egress_qos.type == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TYPE)) && \
2136 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_QUEUE_ID)) && \
2137 (cfg.data.egress_qos.tm_sched.id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TM_SCHED_ID)) && \
2138 (a_val.cmds_bitmask == get_flow_status(it->first.first, it->first.second, ACTION_CMDS_BITMASK)) && \
2139 (a_val.o_vid == get_flow_status(it->first.first, it->first.second, ACTION_O_VID)) && \
2140 (a_val.i_vid == get_flow_status(it->first.first, it->first.second, ACTION_I_VID)) && \
2141 (a_val.o_pbits == get_flow_status(it->first.first, it->first.second, ACTION_O_PBITS)) && \
2142 (a_val.i_pbits == get_flow_status(it->first.first, it->first.second, ACTION_I_PBITS)) && \
2143 (cfg.data.state == get_flow_status(it->first.first, it->first.second, STATE)) && \
2144 (cfg.data.group_id == get_flow_status(it->first.first, it->first.second, GROUP_ID));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002145#ifdef SHOW_FLOW_PARAM
2146 // Flow Parameter
2147 FLOW_PARAM_LOG();
2148#endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002149 if (b_duplicate_flow) {
2150 FLOW_LOG(WARNING, "Flow duplicate", 0);
2151 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
2152 }
2153 }
2154 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002155#endif // FLOW_CHECKER
2156#endif // SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002157
2158 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2159 if (err) {
2160 FLOW_LOG(ERROR, "Flow add failed", err);
2161 return bcm_to_grpc_err(err, "flow add failed");
2162 } else {
2163 FLOW_LOG(INFO, "Flow add ok", err);
2164 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002165 flow_map[std::pair<int, int>(key.flow_id,key.flow_type)] = flow_map.size();
2166 flow_id_counters = flow_map.size();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002167 bcmos_fastlock_unlock(&data_lock, 0);
Girish Gowdra252f4972020-09-07 21:24:01 -07002168
2169 }
Burak Gurdaga0523592021-02-24 15:17:47 +00002170
2171 /*
2172 Enable AES encryption on GEM ports if they are used in downstream unicast flows.
2173 Rationale: We can't do upstream encryption in GPON. This change addresses the common denominator (and also minimum viable)
2174 use case for both technologies which is downstream unicast GEM port encryption. Since the downstream traffic is inherently
2175 broadcast to all the ONUs behind a PON port, encrypting the individual subscriber traffic in this direction is important
2176 and considered good enough in terms of security (See Section 12.1 of G.984.3). For upstream unicast and downstream multicast
2177 GEM encryption, we need to make additional changes specific to XGSPON. This will be done as a future work.
2178 */
2179 if (aes_enabled && (access_intf_id >= 0) && (gemport_id >= GEM_PORT_ID_START) && (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM)) {
2180 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 +05302181 enable_encryption_for_gem_port(access_intf_id, gemport_id, board_technology);
Burak Gurdaga0523592021-02-24 15:17:47 +00002182 } else {
2183 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);
2184 }
2185
Girish Gowdra252f4972020-09-07 21:24:01 -07002186 return Status::OK;
2187}
2188
2189Status FlowRemoveWrapper_(const ::openolt::Flow* request) {
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002190 int32_t access_intf_id = request->access_intf_id();
2191 int32_t onu_id = request->onu_id();
2192 int32_t uni_id = request->uni_id();
2193 uint32_t tech_profile_id = request->tech_profile_id();
Girish Gowdra252f4972020-09-07 21:24:01 -07002194 uint64_t voltha_flow_id = request->flow_id();
2195 Status st;
2196
2197 // If Voltha flow is not installed, return fail
2198 if (! is_voltha_flow_installed(voltha_flow_id)) {
2199 OPENOLT_LOG(ERROR, openolt_log_id, "voltha_flow_id=%lu not found\n", voltha_flow_id);
2200 return ::Status(grpc::StatusCode::NOT_FOUND, "voltha-flow-not-found");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002201 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04002202
Girish Gowdra252f4972020-09-07 21:24:01 -07002203 const device_flow *dev_fl = get_device_flow(voltha_flow_id);
2204 if (dev_fl == NULL) {
2205 OPENOLT_LOG(ERROR, openolt_log_id, "device flow for voltha_flow_id=%lu in the cache is NULL\n", voltha_flow_id);
2206 return ::Status(grpc::StatusCode::INTERNAL, "device-flow-null-in-cache");
2207 }
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002208 std::string flow_type = dev_fl->flow_type;
Girish Gowdra252f4972020-09-07 21:24:01 -07002209 if (dev_fl->is_flow_replicated) {
2210 // Note: Here we are ignoring FlowRemove failures
Girish Gowdra52997cc2022-06-02 20:58:50 -07002211 for (int i=0; i<dev_fl->total_replicated_flows; i++) {
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002212 st = FlowRemove_(dev_fl->params[i].flow_id, flow_type);
Girish Gowdra252f4972020-09-07 21:24:01 -07002213 if (st.error_code() == grpc::StatusCode::OK) {
2214 free_flow_id(dev_fl->params[i].flow_id);
2215 }
2216 }
2217 } else {
2218 // Note: Here we are ignoring FlowRemove failures
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002219 st = FlowRemove_(dev_fl->params[0].flow_id, flow_type);
Girish Gowdra252f4972020-09-07 21:24:01 -07002220 if (st.error_code() == grpc::StatusCode::OK) {
2221 free_flow_id(dev_fl->params[0].flow_id);
2222 }
2223 }
2224 // remove the flow from cache on voltha flow removal
2225 remove_voltha_flow_from_cache(voltha_flow_id);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002226
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002227 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 -07002228 // Remove onu-uni mapping for the pon-gem key
2229 bcmos_fastlock_lock(&symmetric_datapath_flow_id_lock);
2230 symmetric_datapath_flow_id_map.erase(key);
2231 bcmos_fastlock_unlock(&symmetric_datapath_flow_id_lock, 0);
2232
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002233 return Status::OK;
2234}
2235
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002236Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
2237
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002238 bcmolt_flow_cfg cfg;
2239 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002240
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002241 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002242 key.flow_id = flow_id;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002243 if (flow_type == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002244 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002245 } else if (flow_type == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002246 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002247 } else if(flow_type == multicast) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002248 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002249 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002250 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002251 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
2252 }
2253
Jason Huang09b73ea2020-01-08 17:52:05 +08002254 OPENOLT_LOG(INFO, openolt_log_id, "flow remove received for flow_id=%u, flow_type=%s\n",
2255 flow_id, flow_type.c_str());
2256
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002257 bcmos_fastlock_lock(&acl_packet_trap_handler_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002258 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
2259 int32_t gemport_id = -1;
2260 int32_t intf_id = -1;
2261 int16_t acl_id = -1;
2262 if (flow_to_acl_map.count(fl_id_fl_dir) > 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002263
2264 acl_id_intf_id ac_id_if_id = flow_to_acl_map[fl_id_fl_dir];
2265 acl_id = std::get<0>(ac_id_if_id);
2266 intf_id = std::get<1>(ac_id_if_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002267 // cleanup acl only if it is a valid acl. If not valid acl, it may be datapath flow.
2268 if (acl_id >= 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002269 Status resp = handle_acl_rule_cleanup(acl_id, intf_id, flow_type);
Jason Huang09b73ea2020-01-08 17:52:05 +08002270 if (resp.ok()) {
2271 OPENOLT_LOG(INFO, openolt_log_id, "acl removed ok for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2272 flow_to_acl_map.erase(fl_id_fl_dir);
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002273
2274 // 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
2275 if (trap_to_host_pkt_info_with_vlan_for_flow_id.count(flow_id) > 0) {
2276 trap_to_host_pkt_info_with_vlan pkt_info_with_vlan = trap_to_host_pkt_info_with_vlan_for_flow_id[flow_id];
2277 // Formulate the trap_to_host_pkt_info tuple key
2278 trap_to_host_pkt_info pkt_info(std::get<0>(pkt_info_with_vlan),
2279 std::get<1>(pkt_info_with_vlan),
2280 std::get<2>(pkt_info_with_vlan),
2281 std::get<3>(pkt_info_with_vlan));
2282 // Extract the value corresponding to trap_to_host_pkt_info key from trap_to_host_vlan_ids_for_trap_to_host_pkt_info
2283 // The value is a list of vlan_ids for the given trap_to_host_pkt_info key
2284 // Remove the vlan_id from the list that corresponded to the flow being removed.
2285 if (trap_to_host_vlan_ids_for_trap_to_host_pkt_info.count(pkt_info) > 0) {
2286 trap_to_host_vlan_ids_for_trap_to_host_pkt_info[pkt_info].remove(std::get<4>(pkt_info_with_vlan));
2287 } else {
2288 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",
2289 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));
2290 }
2291
2292 } else {
2293 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);
2294 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002295 } else {
2296 OPENOLT_LOG(ERROR, openolt_log_id, "acl remove error for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2297 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002298 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002299 return resp;
2300 }
2301 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002302 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002303
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002304 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002305 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002306 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002307 flowid_to_gemport.erase(key.flow_id);
2308 port_to_flows[port_no].erase(key.flow_id);
2309 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
2310 }
2311 else
2312 {
2313 flowid_to_port.erase(key.flow_id);
2314 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002315 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002316
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002317 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002318
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002319 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002320 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07002321 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 -04002322 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
2323 }
2324
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002325 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002326 if (flow_id_counters != 0) {
2327 std::map<flow_pair, int>::iterator it;
2328 for(it = flow_map.begin(); it != flow_map.end(); it++) {
2329 if (it->first.first == flow_id && it->first.second == key.flow_type) {
2330 flow_id_counters -= 1;
2331 flow_map.erase(it);
Shivanagouda Malaginahallie707d612023-08-22 10:40:25 +00002332 break; /* After match found break from the loop, otherwise leads to crash */
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002333 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002334 }
2335 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002336 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
2337
Jason Huang09b73ea2020-01-08 17:52:05 +08002338 flow_to_acl_map.erase(fl_id_fl_dir);
2339
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002340 bcmos_fastlock_unlock(&data_lock, 0);
2341
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002342 return Status::OK;
2343}
2344
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002345bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
2346 bcmos_errno err;
2347 bcmolt_tm_sched_cfg tm_sched_cfg;
2348 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2349 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
2350
Jason Huangbf45ffb2019-10-30 17:29:02 +08002351 //check TM scheduler has configured or not
2352 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2353 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002354 #ifdef TEST_MODE
2355 // It is impossible to mock the setting of tm_sched_cfg.data.state because
2356 // the actual bcmolt_cfg_get passes the address of tm_sched_cfg.hdr and we cannot
2357 // set the tm_sched_cfg.data.state. So a new stub function is created and address
2358 // of tm_sched_cfg is passed. This is one-of case where we need to add test specific
2359 // code in production code.
2360 err = bcmolt_cfg_get__tm_sched_stub(dev_id, &tm_sched_cfg);
2361 #else
Jason Huangbf45ffb2019-10-30 17:29:02 +08002362 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002363 #endif
Jason Huangbf45ffb2019-10-30 17:29:02 +08002364 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07002365 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 +08002366 return err;
2367 }
2368 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
2369 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
2370 return BCM_ERR_OK;
2371 }
2372
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002373 // bcmbal_tm_sched_owner
2374 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2375
2376 /**< The output of the tm_sched object instance */
2377 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
2378
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002379 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002380 // In upstream it is NNI scheduler
2381 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 -08002382 } else if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002383 // In downstream it is PON scheduler
2384 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2385 }
2386
2387 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2388
2389 // bcmbal_tm_sched_type
2390 // set the deafult policy to strict priority
2391 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2392
2393 // num_priorities: Max number of strict priority scheduling elements
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002394 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, NUM_OF_PRIORITIES);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002395
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002396 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2397 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002398 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
2399 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002400 return err;
2401 }
2402
2403 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2404 direction.c_str(), tm_sched_key.id, intf_id);
2405 return BCM_ERR_OK;
2406}
2407
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002408bcmos_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 -07002409 uint32_t alloc_id, ::tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
2410 ::tech_profile::SchedulingPolicy sched_policy, ::tech_profile::TrafficShapingInfo tf_sh_info,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002411 uint32_t tech_profile_id) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002412
2413 bcmos_errno err;
2414
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002415 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002416 bcmolt_tm_sched_cfg tm_sched_cfg;
2417 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002418 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 -04002419
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002420 // bcmbal_tm_sched_owner
2421 // In downstream it is sub_term scheduler
2422 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002423
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002424 /**< The output of the tm_sched object instance */
2425 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002426
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002427 // bcmbal_tm_sched_parent
2428 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2429 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 +00002430 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 +00002431 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 +00002432 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002433 be achieved using the' virtual' type of attachment.
2434 tm_sched_owner.u.sub_term.intf_id = intf_id;
2435 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2436 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002437
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002438 // bcmbal_tm_sched_type
2439 // set the deafult policy to strict priority
2440 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002441
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002442 // num_priorities: Max number of strict priority scheduling elements
2443 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002444
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002445 // bcmbal_tm_shaping
2446 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2447 uint32_t cir = tf_sh_info.cir();
2448 uint32_t pir = tf_sh_info.pir();
2449 uint32_t burst = tf_sh_info.pbs();
2450 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2451 cir, pir, burst);
2452 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2453 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2454 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2455 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2456 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2457 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002458 }
2459
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002460 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002461 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002462 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Girish Gowdra72cbee92021-11-05 15:16:18 -07002463intf_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, \
2464port_no, tm_sched_cfg.hdr.hdr.err_text, err);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002465 return err;
2466 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002467 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2468uni_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 -08002469
2470 } else { //upstream
Arthur Syu094df162022-04-21 17:50:06 +08002471 std::string intf_technology = intf_technologies[intf_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002472 bcmolt_itupon_alloc_cfg cfg;
2473 bcmolt_itupon_alloc_key key = { };
2474 key.pon_ni = intf_id;
2475 key.alloc_id = alloc_id;
Arthur Syu094df162022-04-21 17:50:06 +08002476 int bw_granularity = (intf_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
Burak Gurdag623fada2021-04-20 22:02:36 +00002477 /*
2478 PIR: Maximum Bandwidth
2479 CIR: Assured Bandwidth
2480 GIR: Fixed Bandwidth
2481 */
Burak Gurdag03919c72020-02-04 22:46:57 +00002482 int pir_bw = tf_sh_info.pir()*125; // conversion from kbps to bytes/sec
2483 int cir_bw = tf_sh_info.cir()*125; // conversion from kbps to bytes/sec
Burak Gurdag623fada2021-04-20 22:02:36 +00002484 int gir_bw = tf_sh_info.gir()*125; // conversion from kbps to bytes/sec
2485 int guaranteed_bw = cir_bw+gir_bw;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002486 //offset to match bandwidth granularity
2487 int offset_pir_bw = pir_bw%bw_granularity;
Burak Gurdag623fada2021-04-20 22:02:36 +00002488 int offset_gir_bw = gir_bw%bw_granularity;
2489 int offset_guaranteed_bw = guaranteed_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002490
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002491 pir_bw = pir_bw - offset_pir_bw;
Burak Gurdag623fada2021-04-20 22:02:36 +00002492 gir_bw = gir_bw - offset_gir_bw;
2493 guaranteed_bw = guaranteed_bw - offset_guaranteed_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002494
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002495 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002496
Burak Gurdag623fada2021-04-20 22:02:36 +00002497 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);
2498
2499 if (pir_bw == 0) {
2500 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be at least %d bytes/sec\n",
2501 (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2502 return BCM_ERR_PARM;
2503 } else if (pir_bw < guaranteed_bw) {
2504 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed bandwidth (%d)\n",
2505 pir_bw, guaranteed_bw);
2506 return BCM_ERR_PARM;
2507 }
2508
2509 // Setting additional bw eligibility and validating bw provisionings
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002510 switch (additional_bw) {
Burak Gurdag623fada2021-04-20 22:02:36 +00002511
2512 case tech_profile::AdditionalBW::AdditionalBW_BestEffort: //AdditionalBW_BestEffort - For T-Cont types 4 & 5
2513 if (pir_bw == guaranteed_bw) {
2514 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2515bandwidth for additional bandwidth eligibility of type Best Effort\n");
2516 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002517 }
2518 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2519 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002520
2521 case tech_profile::AdditionalBW::AdditionalBW_NA: //AdditionalBW_NA - For T-Cont types 3 & 5
2522 if (guaranteed_bw == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002523 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2524additional bandwidth eligibility of type Non-Assured (NA)\n");
2525 return BCM_ERR_PARM;
Burak Gurdag623fada2021-04-20 22:02:36 +00002526 } else if (pir_bw == guaranteed_bw) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002527 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
Burak Gurdag623fada2021-04-20 22:02:36 +00002528bandwidth for additional bandwidth eligibility of type Non-Assured\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002529 return BCM_ERR_PARM;
2530 }
2531 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2532 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002533
2534 case tech_profile::AdditionalBW::AdditionalBW_None: //AdditionalBW_None - For T-Cont types 1 & 2
2535 if (guaranteed_bw != pir_bw) {
2536 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be equal to maximum bandwidth \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002537for additional bandwidth eligibility of type None\n");
2538 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002539 }
2540 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2541 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002542
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002543 default:
Burak Gurdag623fada2021-04-20 22:02:36 +00002544 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid additional bandwidth eligibility value (%d) supplied.\n", additional_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002545 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002546 }
Burak Gurdag623fada2021-04-20 22:02:36 +00002547
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002548 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2549 in a fine granularity. */
2550 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
Burak Gurdag623fada2021-04-20 22:02:36 +00002551 /* Since we can assign minimum 64000 bytes/sec for cbr_rt_bw, we prefer assigning
2552 gir_bw to cbr_nrt_bw to allow smaller amounts.
2553 TODO: Specify CBR_RT_BW and CBR_NRT_BW separately from VOLTHA */
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002554 /* Fixed Bandwidth with no critical requirement of shaping */
Burak Gurdag623fada2021-04-20 22:02:36 +00002555 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, gir_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002556 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
Burak Gurdag623fada2021-04-20 22:02:36 +00002557 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, guaranteed_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002558 /* Maximum allocated bandwidth allowed for this alloc ID */
2559 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
Burak Gurdag623fada2021-04-20 22:02:36 +00002560
2561 if (pir_bw == gir_bw) { // T-Cont Type 1 --> set alloc type to NONE
2562 // the condition cir_bw == 0 is implicitly satistied
2563 OPENOLT_LOG(INFO, openolt_log_id, "Setting alloc type to NONE since maximum bandwidth is equal to fixed bandwidth\n");
2564 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NONE);
2565 } else { // For other T-Cont types, set alloc type to NSR. TODO: read the default from a config file.
2566 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
2567 }
2568
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002569 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002570 for skipped allocations during quiet window */
2571 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2572 /**< Allocation Profile index for CBR non-RT Bandwidth */
2573 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2574 /**< Allocation Profile index for CBR RT Bandwidth */
2575 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2576 /**< Alloc ID Weight used in case of Extended DBA mode */
2577 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2578 /**< Alloc ID Priority used in case of Extended DBA mode */
2579 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2580 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002581
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302582 bcmolt_onu_state onu_state;
2583 bool wait_for_alloc_cfg_cmplt = false;
2584 err = get_onu_state((bcmolt_interface)intf_id, (bcmolt_onu_id)onu_id, &onu_state);
2585 if (err) {
2586 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch onu status, intf_id = %d, onu_id = %d, err = %s\n",
2587 intf_id, onu_id, bcmos_strerror(err));
2588 return err;
2589 } else if (onu_state == BCMOLT_ONU_STATE_ACTIVE) {
2590 wait_for_alloc_cfg_cmplt = true;
2591 }
2592
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002593 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002594 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002595 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 -07002596port_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 -08002597 return err;
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302598 } else if (wait_for_alloc_cfg_cmplt) {
2599 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
2600 if (err) {
2601 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 +05302602port_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 +05302603 return err;
Girish Gowdra72cbee92021-11-05 15:16:18 -07002604 }
2605 } else {
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302606 OPENOLT_LOG(INFO, openolt_log_id, "onu not active, not waiting for alloc cfg complete, onu_state = %d, intf = %d, onu=%d\n",
2607 onu_state, intf_id, onu_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302608 }
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302609
Girish Gowdra96461052019-11-22 20:13:59 +05302610 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
2611port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
2612
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002613 }
2614
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002615 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002616}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002617
Girish Gowdra252f4972020-09-07 21:24:01 -07002618Status CreateTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002619 uint32_t intf_id = traffic_scheds->intf_id();
2620 uint32_t onu_id = traffic_scheds->onu_id();
2621 uint32_t uni_id = traffic_scheds->uni_id();
2622 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002623 std::string direction;
2624 unsigned int alloc_id;
Girish Gowdra252f4972020-09-07 21:24:01 -07002625 ::tech_profile::SchedulerConfig sched_config;
2626 ::tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002627 uint32_t priority;
2628 uint32_t weight;
Girish Gowdra252f4972020-09-07 21:24:01 -07002629 ::tech_profile::SchedulingPolicy sched_policy;
2630 ::tech_profile::TrafficShapingInfo traffic_shaping_info;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002631 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002632 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002633
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002634 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002635 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002636
2637 direction = GetDirection(traffic_sched.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002638 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002639 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002640 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002641
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002642 alloc_id = traffic_sched.alloc_id();
2643 sched_config = traffic_sched.scheduler();
2644 additional_bw = sched_config.additional_bw();
2645 priority = sched_config.priority();
2646 weight = sched_config.weight();
2647 sched_policy = sched_config.sched_policy();
2648 traffic_shaping_info = traffic_sched.traffic_shaping_info();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002649 tech_profile_id = traffic_sched.tech_profile_id();
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002650 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002651 sched_policy, traffic_shaping_info, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002652 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002653 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002654 return bcm_to_grpc_err(err, "Failed to create scheduler");
2655 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002656 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002657 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002658}
Jonathan Davis70c21812018-07-19 15:32:10 -04002659
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002660bcmos_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 -04002661
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002662 bcmos_errno err;
Girish Gowdra72cbee92021-11-05 15:16:18 -07002663 bcmolt_onu_state onu_state;
Girish Gowdra96461052019-11-22 20:13:59 +05302664 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002665
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002666 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002667 bcmolt_itupon_alloc_cfg cfg;
2668 bcmolt_itupon_alloc_key key = { };
2669 key.pon_ni = intf_id;
2670 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302671 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002672
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302673 bcmolt_onu_state onu_state;
2674 bool wait_for_alloc_cfg_cmplt = false;
2675 err = get_onu_state((bcmolt_interface)intf_id, (bcmolt_onu_id)onu_id, &onu_state);
2676 if (err) {
2677 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch onu status, intf_id = %d, onu_id = %d, err = %s\n",
2678 intf_id, onu_id, bcmos_strerror(err));
2679 return err;
2680 } else if (onu_state == BCMOLT_ONU_STATE_ACTIVE) {
2681 wait_for_alloc_cfg_cmplt = true;
2682 }
2683
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002684 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002685 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2686 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07002687 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s (%d)\n",
2688 direction.c_str(), intf_id, alloc_id, cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002689 return err;
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302690 } else if (wait_for_alloc_cfg_cmplt) {
2691 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2692 if (err) {
2693 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2694pon_intf %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,intf_id,alloc_id, bcmos_strerror(err));
2695 return err;
2696 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302697 } else {
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302698 OPENOLT_LOG(INFO, openolt_log_id, "onu not active, not waiting for alloc cfg complete, onu_state = %d, intf = %d, onu=%d\n",
2699 onu_state, intf_id, onu_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302700 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002701 } else if (direction == downstream) {
2702 bcmolt_tm_sched_cfg cfg;
2703 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002704
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002705 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2706 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302707 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002708 } else {
2709 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2710 return BCM_ERR_OK;
2711 }
Girish Gowdra96461052019-11-22 20:13:59 +05302712
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002713 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2714 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2715 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002716 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
Girish Gowdra72cbee92021-11-05 15:16:18 -07002717intf_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 +00002718 return err;
2719 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002720 }
2721
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002722 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d, tech_profile_id %d\n",
2723 direction.c_str(), sched_id, intf_id, onu_id, tech_profile_id);
2724 free_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002725 return BCM_ERR_OK;
2726}
2727
Girish Gowdra252f4972020-09-07 21:24:01 -07002728Status RemoveTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002729 uint32_t intf_id = traffic_scheds->intf_id();
2730 uint32_t onu_id = traffic_scheds->onu_id();
2731 uint32_t uni_id = traffic_scheds->uni_id();
2732 std::string direction;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002733 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002734 bcmos_errno err;
2735
2736 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002737 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002738
2739 direction = GetDirection(traffic_sched.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002740 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002741 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002742 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002743
2744 int alloc_id = traffic_sched.alloc_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002745 int tech_profile_id = traffic_sched.tech_profile_id();
2746 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002747 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002748 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002749 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2750 }
2751 }
2752 return Status::OK;
2753}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002754
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002755bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2756 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002757 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002758 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2759 bcmolt_tm_qmp_key tm_qmp_key;
2760 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002761
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002762 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2763 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002764 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed tm queue mapping profile count is 16.\n");
2765 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002766 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002767
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002768 tm_qmp_key.id = tm_qmp_id;
2769 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2770 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2771 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002772
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002773 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2774 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2775 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002776 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2777 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002778
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002779 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002780 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002781 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2782 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002783 return err;
2784 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002785
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002786 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2787 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002788 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002789}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002790
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002791bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2792 bcmos_errno err;
2793 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2794 bcmolt_tm_qmp_key tm_qmp_key;
2795 tm_qmp_key.id = tm_qmp_id;
2796
2797 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2798 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2799 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002800 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2801 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002802 return err;
2803 }
2804
2805 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2806 tm_qmp_key.id);
2807 return BCM_ERR_OK;
2808}
2809
2810bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2811 bcmos_errno err;
2812
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002813 /* Create default queues on the given PON/NNI scheduler */
2814 for (int queue_id = 0; queue_id < NUMBER_OF_DEFAULT_INTERFACE_QUEUES; queue_id++) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002815 bcmolt_tm_queue_cfg tm_queue_cfg;
2816 bcmolt_tm_queue_key tm_queue_key = {};
2817 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2818 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002819 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2820 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2821 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002822
2823 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2824 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2825 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2826
2827 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2828 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002829 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", \
2830 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 +00002831 return err;
2832 }
2833
2834 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2835 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2836 }
2837 return BCM_ERR_OK;
2838}
2839
Sridhar Ravindra57d7eb92025-06-04 13:39:43 +05302840bcmos_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 +00002841 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 +00002842 bcmos_errno err;
2843 bcmolt_tm_queue_cfg cfg;
2844 bcmolt_tm_queue_key key = { };
Sridhar Ravindra57d7eb92025-06-04 13:39:43 +05302845 OPENOLT_LOG(INFO, openolt_log_id, "creating %s queue. access_intf_id = %d, nni_intf_id = %d, onu_id = %d, uni_id = %d \
2846gemport_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 +00002847
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002848 key.sched_id = (direction == upstream) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002849 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002850
2851 if (priority > 7) {
2852 return BCM_ERR_RANGE;
2853 }
2854
2855 /* FIXME: The upstream queues have to be created once only.
2856 The upstream queues on the NNI scheduler are shared by all subscribers.
2857 When the first scheduler comes in, the queues get created, and are re-used by all others.
2858 Also, these queues should be present until the last subscriber exits the system.
2859 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2860
2861 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2862 for each GEM in TECH PROFILE */
2863 key.id = queue_id_list[priority];
2864
2865 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2866 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2867 key.id = 0;
2868 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2869 }
2870 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2871 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2872 }
2873 else {
2874 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2875 }
2876
2877 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2878
2879 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2880 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
Girish Gowdra5287fde2021-07-31 00:41:45 +00002881 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002882
2883 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2884 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002885 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
Girish Gowdra72cbee92021-11-05 15:16:18 -07002886sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, tech_profile_id %d, err = %s (%d)\n", \
2887 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 +00002888 return err;
2889 }
2890
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302891 if (direction == upstream || direction == downstream) {
Thiyagarajan Subramani19168f52021-05-25 23:26:41 +05302892 Status st = install_gem_port(access_intf_id, onu_id, uni_id, gemport_id, board_technology);
Girish Gowdra252f4972020-09-07 21:24:01 -07002893 if (st.error_code() != grpc::StatusCode::ALREADY_EXISTS && st.error_code() != grpc::StatusCode::OK) {
2894 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);
2895 return BCM_ERR_INTERNAL;
2896 }
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002897 if (direction == upstream) {
2898 // Create the pon-gem to onu-uni mapping
2899 pon_gem pg(access_intf_id, gemport_id);
2900 onu_uni ou(onu_id, uni_id);
2901 bcmos_fastlock_lock(&pon_gem_to_onu_uni_map_lock);
2902 pon_gem_to_onu_uni_map[pg] = ou;
2903 bcmos_fastlock_unlock(&pon_gem_to_onu_uni_map_lock, 0);
2904 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002905 }
2906
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002907 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 +00002908intf_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 +00002909 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002910}
2911
Girish Gowdra252f4972020-09-07 21:24:01 -07002912Status CreateTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002913 uint32_t intf_id = traffic_queues->intf_id();
Sridhar Ravindra57d7eb92025-06-04 13:39:43 +05302914 uint32_t nni_intf_id = traffic_queues->network_intf_id();
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002915 uint32_t onu_id = traffic_queues->onu_id();
2916 uint32_t uni_id = traffic_queues->uni_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002917 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002918 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002919 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002920 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002921 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 +00002922
Sridhar Ravindra57d7eb92025-06-04 13:39:43 +05302923 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 +00002924 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2925 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2926 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2927 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002928 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002929
2930 direction = GetDirection(traffic_queue.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002931 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002932 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002933 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002934
2935 queues_priority_q[i] = traffic_queue.priority();
2936 queues_pbit_map[i] = traffic_queue.pbit_map();
2937 }
2938
2939 std::vector<uint32_t> tmq_map_profile(8, 0);
2940 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2941 queues_priority_q, COUNT_OF(queues_priority_q));
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002942 sched_id = (direction == upstream) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002943 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002944
2945 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2946 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002947 err = CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2948 if (err != BCM_ERR_OK) {
2949 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2950 return bcm_to_grpc_err(err, "Failed to create tm queue mapping profile");
2951 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002952 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2953 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2954 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2955 }
2956 }
2957
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002958 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002959 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002960
2961 direction = GetDirection(traffic_queue.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002962 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002963 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002964 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002965
Sridhar Ravindra57d7eb92025-06-04 13:39:43 +05302966 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 +00002967
Girish Gowdruf26cf882019-05-01 23:47:58 -07002968 // If the queue exists already, lets not return failure and break the loop.
2969 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002970 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002971 return bcm_to_grpc_err(err, "Failed to create queue");
2972 }
2973 }
2974 return Status::OK;
2975}
2976
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002977bcmos_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 +00002978 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 +00002979 bcmolt_tm_queue_cfg cfg;
2980 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002981 bcmos_errno err;
2982
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302983 // Gemports are bi-directional (except in multicast case). We create the gem port when we create the
2984 // upstream/downstream queue (see CreateQueue function) and it makes sense to delete them when remove the queues.
2985 // For multicast case we do not manage the install/remove of gem port in agent application. It is managed by BAL.
2986 if (direction == upstream || direction == downstream) {
Thiyagarajan Subramani19168f52021-05-25 23:26:41 +05302987 Status st = remove_gem_port(access_intf_id, onu_id, uni_id, gemport_id, board_technology);
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302988 if (st.error_code() != grpc::StatusCode::OK) {
2989 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 -07002990 // We should further cleanup proceed, do not return error yet..
2991 // return BCM_ERR_INTERNAL;
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302992 }
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002993 if (direction == upstream) {
2994 // Remove the pon-gem to onu-uni mapping
2995 pon_gem pg(access_intf_id, gemport_id);
2996 bcmos_fastlock_lock(&pon_gem_to_onu_uni_map_lock);
2997 pon_gem_to_onu_uni_map.erase(pg);
2998 bcmos_fastlock_unlock(&pon_gem_to_onu_uni_map_lock, 0);
2999 }
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05303000 }
3001
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003002 if (direction == downstream) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00003003 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction, tech_profile_id)) {
3004 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 +00003005 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003006 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003007 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 -08003008 return BCM_ERR_OK;
3009 }
3010 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003011 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
3012 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003013 return BCM_ERR_OK;
3014 }
3015
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003016 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
3017 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
3018 // Reset the queue id to 0 when using fixed queue.
3019 key.id = 0;
3020 }
3021 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
3022 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
3023 }
3024 else {
3025 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
3026 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003027
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003028 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
3029 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003030 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003031 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 -07003032tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s (%d)\n",
3033 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 -08003034 return err;
3035 }
3036
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003037 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
3038intf_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 -08003039
3040 return BCM_ERR_OK;
3041}
3042
Girish Gowdra252f4972020-09-07 21:24:01 -07003043Status RemoveTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003044 uint32_t intf_id = traffic_queues->intf_id();
Sridhar Ravindra57d7eb92025-06-04 13:39:43 +05303045 uint32_t nni_intf_id = traffic_queues->network_intf_id();
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003046 uint32_t onu_id = traffic_queues->onu_id();
3047 uint32_t uni_id = traffic_queues->uni_id();
3048 uint32_t port_no = traffic_queues->port_no();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00003049 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003050 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003051 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003052 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003053 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 -07003054 Status ret_code = Status::OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003055
Sridhar Ravindra57d7eb92025-06-04 13:39:43 +05303056 OPENOLT_LOG(DEBUG, openolt_log_id, "Remove Traffic Queues for nni_intf_id %d, intf_id %d\n", nni_intf_id, intf_id);
3057
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003058 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07003059 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003060
3061 direction = GetDirection(traffic_queue.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08003062 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003063 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08003064 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003065
Burak Gurdag2f2618c2020-04-23 13:20:30 +00003066 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 -08003067 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003068 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdra72cbee92021-11-05 15:16:18 -07003069 ret_code = bcm_to_grpc_err(err, "Failed to remove one or more queues");
3070 // Do not return here. We should continue to remove the remaining queues and its associated gem ports
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003071 }
Jonathan Davis70c21812018-07-19 15:32:10 -04003072 }
3073
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08003074 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE && (direction == upstream || \
3075 direction == downstream && is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id))) {
3076 sched_id = (direction == upstream) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00003077 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003078
3079 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
3080 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05003081 err = RemoveTrafficQueueMappingProfile(tm_qmp_id);
3082 if (err != BCM_ERR_OK) {
3083 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, err = %s\n", bcmos_strerror(err));
3084 return bcm_to_grpc_err(err, "Failed to remove tm queue mapping profile");
3085 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003086 }
3087 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003088 clear_qos_type(intf_id, onu_id, uni_id);
Girish Gowdra72cbee92021-11-05 15:16:18 -07003089 return ret_code;
Jonathan Davis70c21812018-07-19 15:32:10 -04003090}
Jason Huangbf45ffb2019-10-30 17:29:02 +08003091
Girish Gowdra252f4972020-09-07 21:24:01 -07003092Status PerformGroupOperation_(const ::openolt::Group *group_cfg) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003093
3094 bcmos_errno err;
3095 bcmolt_group_key key = {};
3096 bcmolt_group_cfg grp_cfg_obj;
3097 bcmolt_group_members_update grp_mem_upd;
3098 bcmolt_members_update_command grp_mem_upd_cmd;
3099 bcmolt_group_member_info member_info = {};
3100 bcmolt_group_member_info_list_u8 members = {};
3101 bcmolt_intf_ref interface_ref = {};
3102 bcmolt_egress_qos egress_qos = {};
3103 bcmolt_tm_sched_ref tm_sched_ref = {};
3104 bcmolt_action a_val = {};
3105
3106 uint32_t group_id = group_cfg->group_id();
3107
3108 OPENOLT_LOG(INFO, openolt_log_id, "PerformGroupOperation request received for Group %d\n", group_id);
3109
3110 if (group_id >= 0) {
3111 key.id = group_id;
3112 }
3113 else {
3114 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
3115 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
3116 }
3117
3118 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3119 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
3120
3121 OPENOLT_LOG(INFO, openolt_log_id, "Checking if Group %d exists...\n",group_id);
3122
3123 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
3124 if (err != BCM_ERR_OK) {
3125 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
3126 return bcm_to_grpc_err(err, "Error in querying group");
3127 }
3128
3129 members.len = group_cfg->members_size();
3130
3131 // IMPORTANT: A member cannot be added to a group if the group type is not determined.
3132 // Group type is determined after a flow is assigned to it.
3133 // Therefore, a group must be created first, then a flow (with multicast type) must be assigned to it.
3134 // Only then we can add members to the group.
3135
3136 // if group does not exist, create it and return.
3137 if (grp_cfg_obj.data.state == BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
3138
3139 if (members.len != 0) {
3140 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);
3141 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Non-empty member list given for non-existent group");
3142 } else {
3143
3144 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3145 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, cookie, key.id);
3146
3147 /* Setting group actions and action parameters, if any.
3148 Only remove_outer_tag and translate_inner_tag actions and i_vid action parameter
3149 are supported for multicast groups in BAL 3.1.
3150 */
3151 const ::openolt::Action& action = group_cfg->action();
3152 const ::openolt::ActionCmd &cmd = action.cmd();
3153
3154 bcmolt_action_cmd_id cmd_bmask = BCMOLT_ACTION_CMD_ID_NONE;
3155 if (cmd.remove_outer_tag()) {
3156 OPENOLT_LOG(INFO, openolt_log_id, "Action remove_outer_tag applied to Group %d.\n", group_id);
3157 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
3158 }
3159
3160 if (cmd.translate_inner_tag()) {
3161 OPENOLT_LOG(INFO, openolt_log_id, "Action translate_inner_tag applied to Group %d.\n", group_id);
3162 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG);
3163 }
3164
3165 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, cmd_bmask);
3166
3167 if (action.i_vid()) {
3168 OPENOLT_LOG(INFO, openolt_log_id, "Setting action parameter i_vid=%d for Group %d.\n", action.i_vid(), group_id);
3169 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
3170 }
3171
3172 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, action, a_val);
3173
3174 // Create group
3175 err = bcmolt_cfg_set(dev_id, &(grp_cfg_obj.hdr));
3176
3177 if (BCM_ERR_OK != err) {
3178 BCM_LOG(ERROR, openolt_log_id, "Failed to create Group %d, err = %s (%d)\n", key.id, bcmos_strerror(err), err);
3179 return bcm_to_grpc_err(err, "Error in creating group");
3180 }
3181
3182 BCM_LOG(INFO, openolt_log_id, "Group %d has been created and configured with empty member list.\n", key.id);
3183 return Status::OK;
3184 }
3185 }
3186
3187 // The group already exists. Continue configuring it according to the update member command.
3188
3189 OPENOLT_LOG(INFO, openolt_log_id, "Configuring existing Group %d.\n",group_id);
3190
3191 // MEMBER LIST CONSTRUCTION
3192 // Note that members.len can be 0 here. if the group already exists and the command is SET then sending
3193 // empty list to the group is a legit operation and this actually empties the member list.
3194 members.arr = (bcmolt_group_member_info*)bcmos_calloc((members.len)*sizeof(bcmolt_group_member_info));
3195
3196 if (!members.arr) {
3197 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to allocate memory for group member list.\n");
3198 return grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "Memory exhausted during member list creation");
3199 }
3200
3201 /* SET GROUP MEMBERS UPDATE COMMAND */
Girish Gowdra252f4972020-09-07 21:24:01 -07003202 ::openolt::Group::GroupMembersCommand command = group_cfg->command();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003203 switch(command) {
Girish Gowdra252f4972020-09-07 21:24:01 -07003204 case ::openolt::Group::SET_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003205 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_SET;
3206 OPENOLT_LOG(INFO, openolt_log_id, "Setting %d members for Group %d.\n", members.len, group_id);
3207 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003208 case ::openolt::Group::ADD_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003209 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_ADD;
3210 OPENOLT_LOG(INFO, openolt_log_id, "Adding %d members to Group %d.\n", members.len, group_id);
3211 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003212 case ::openolt::Group::REMOVE_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003213 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_REMOVE;
3214 OPENOLT_LOG(INFO, openolt_log_id, "Removing %d members from Group %d.\n", members.len, group_id);
3215 break;
3216 default :
3217 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid value %d for group member command.\n", command);
3218 bcmos_free(members.arr);
3219 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group member command");
3220 }
3221
3222 // SET MEMBERS LIST
3223 for (int i = 0; i < members.len; i++) {
3224
Girish Gowdra252f4972020-09-07 21:24:01 -07003225 if (command == ::openolt::Group::REMOVE_MEMBERS) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003226 OPENOLT_LOG(INFO, openolt_log_id, "Removing group member %d from group %d\n",i,key.id);
3227 } else {
3228 OPENOLT_LOG(INFO, openolt_log_id, "Adding group member %d to group %d\n",i,key.id);
3229 }
3230
Girish Gowdra252f4972020-09-07 21:24:01 -07003231 ::openolt::GroupMember *member = (::openolt::GroupMember *) &group_cfg->members()[i];
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003232
3233 // Set member interface type
Girish Gowdra252f4972020-09-07 21:24:01 -07003234 ::openolt::GroupMember::InterfaceType if_type = member->interface_type();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003235 switch(if_type){
Girish Gowdra252f4972020-09-07 21:24:01 -07003236 case ::openolt::GroupMember::PON :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003237 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_PON);
3238 OPENOLT_LOG(INFO, openolt_log_id, "Interface type PON is assigned to GroupMember %d\n",i);
3239 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003240 case ::openolt::GroupMember::EPON_1G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003241 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_1_G);
3242 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_1G is assigned to GroupMember %d\n",i);
3243 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003244 case ::openolt::GroupMember::EPON_10G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003245 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_10_G);
3246 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_10G is assigned to GroupMember %d\n",i);
3247 break;
3248 default :
3249 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid interface type value %d for GroupMember %d.\n",if_type,i);
3250 bcmos_free(members.arr);
3251 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface type for a group member");
3252 }
3253
3254 // Set member interface id
3255 if (member->interface_id() >= 0) {
3256 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_id, member->interface_id());
3257 OPENOLT_LOG(INFO, openolt_log_id, "Interface %d is assigned to GroupMember %d\n", member->interface_id(), i);
3258 } else {
3259 bcmos_free(members.arr);
3260 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface id for a group member");
3261 }
3262
3263 // Set member interface_ref
3264 BCMOLT_FIELD_SET(&member_info, group_member_info, intf, interface_ref);
3265
3266 // Set member gem_port_id. This must be a multicast gemport.
3267 if (member->gem_port_id() >= 0) {
3268 BCMOLT_FIELD_SET(&member_info, group_member_info, svc_port_id, member->gem_port_id());
3269 OPENOLT_LOG(INFO, openolt_log_id, "GEM Port %d is assigned to GroupMember %d\n", member->gem_port_id(), i);
3270 } else {
3271 bcmos_free(members.arr);
3272 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid gem port id for a group member");
3273 }
3274
3275 // Set member scheduler id and queue_id
3276 uint32_t tm_sched_id = get_default_tm_sched_id(member->interface_id(), downstream);
3277 OPENOLT_LOG(INFO, openolt_log_id, "Scheduler %d is assigned to GroupMember %d\n", tm_sched_id, i);
3278 BCMOLT_FIELD_SET(&tm_sched_ref, tm_sched_ref, id, tm_sched_id);
3279 BCMOLT_FIELD_SET(&egress_qos, egress_qos, tm_sched, tm_sched_ref);
3280
3281 // We assume that all multicast traffic destined to a PON port is using the same fixed queue.
3282 uint32_t tm_queue_id;
3283 if (member->priority() >= 0 && member->priority() < NUMBER_OF_DEFAULT_INTERFACE_QUEUES) {
3284 tm_queue_id = queue_id_list[member->priority()];
3285 OPENOLT_LOG(INFO, openolt_log_id, "Queue %d is assigned to GroupMember %d\n", tm_queue_id, i);
3286 BCMOLT_FIELD_SET(&egress_qos, egress_qos, type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
3287 BCMOLT_FIELD_SET(&egress_qos.u.fixed_queue, egress_qos_fixed_queue, queue_id, tm_queue_id);
3288 } else {
3289 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid fixed queue priority/ID %d for GroupMember %d\n", member->priority(), i);
3290 bcmos_free(members.arr);
3291 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid queue priority for a group member");
3292 }
3293
3294 BCMOLT_FIELD_SET(&member_info, group_member_info, egress_qos, egress_qos);
3295 BCMOLT_ARRAY_ELEM_SET(&(members), i, member_info);
3296 }
3297
3298 BCMOLT_OPER_INIT(&grp_mem_upd, group, members_update, key);
3299 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.members, members);
3300 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.command, grp_mem_upd_cmd);
3301
3302 err = bcmolt_oper_submit(dev_id, &(grp_mem_upd.hdr));
3303 bcmos_free(members.arr);
3304
3305 if (BCM_ERR_OK != err) {
3306 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);
3307 return bcm_to_grpc_err(err, "Failed to submit members update operation for the group");
3308 }
3309
3310 OPENOLT_LOG(INFO, openolt_log_id, "Successfully submitted members update operation for Group %d\n", key.id);
3311
3312 return Status::OK;
3313}
Burak Gurdageb4ca2e2020-06-15 07:48:26 +00003314
3315Status DeleteGroup_(uint32_t group_id) {
3316
3317 bcmos_errno err = BCM_ERR_OK;
3318 bcmolt_group_cfg grp_cfg_obj;
3319 bcmolt_group_key key = {};
3320
3321
3322 OPENOLT_LOG(INFO, openolt_log_id, "Delete request received for group %d\n", group_id);
3323
3324 if (group_id >= 0) {
3325 key.id = group_id;
3326 } else {
3327 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
3328 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
3329 }
3330
3331 /* init the BAL INIT API */
3332 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3333
3334 OPENOLT_LOG(DEBUG, openolt_log_id, "Checking if group %d exists...\n",group_id);
3335
3336 // CONFIGURE GROUP MEMBERS
3337 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
3338 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
3339
3340 if (err != BCM_ERR_OK) {
3341 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
3342 return bcm_to_grpc_err(err, "Error in querying group");
3343 }
3344
3345 if (grp_cfg_obj.data.state != BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
3346 OPENOLT_LOG(DEBUG, openolt_log_id, "Group %d exists. Will be deleted.\n",group_id);
3347 err = bcmolt_cfg_clear(dev_id, &(grp_cfg_obj.hdr));
3348 if (err != BCM_ERR_OK) {
3349 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d cannot be deleted err = %s (%d).\n", group_id, bcmos_strerror(err), err);
3350 return bcm_to_grpc_err(err, "Failed to delete group");;
3351 }
3352 } else {
3353 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d does not exist.\n", group_id);
3354 return Status(grpc::StatusCode::NOT_FOUND, "Group not found");
3355 }
3356
3357 OPENOLT_LOG(INFO, openolt_log_id, "Group %d has been deleted successfully.\n", group_id);
3358 return Status::OK;
Jason Huang1d9cfce2020-05-20 22:58:47 +08003359}
3360
Girish Gowdra252f4972020-09-07 21:24:01 -07003361Status GetLogicalOnuDistanceZero_(uint32_t intf_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003362 bcmos_errno err = BCM_ERR_OK;
3363 uint32_t mld = 0;
3364 double LD0;
3365
3366 err = getOnuMaxLogicalDistance(intf_id, &mld);
3367 if (err != BCM_ERR_OK) {
3368 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3369 }
3370
3371 LD0 = LOGICAL_DISTANCE(mld*1000, MINIMUM_ONU_RESPONSE_RANGING_TIME, ONU_BIT_TRANSMISSION_DELAY);
3372 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance zero is %f, (PON %d)\n", LD0, intf_id);
3373 response->set_intf_id(intf_id);
3374 response->set_logical_onu_distance_zero(LD0);
3375
3376 return Status::OK;
3377}
3378
Girish Gowdra252f4972020-09-07 21:24:01 -07003379Status GetLogicalOnuDistance_(uint32_t intf_id, uint32_t onu_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003380 bcmos_errno err = BCM_ERR_OK;
3381 bcmolt_itu_onu_params itu = {};
3382 bcmolt_onu_cfg onu_cfg;
3383 bcmolt_onu_key onu_key = {};
3384 uint32_t mld = 0;
3385 double LDi;
3386
3387 onu_key.pon_ni = intf_id;
3388 onu_key.onu_id = onu_id;
3389
3390 err = getOnuMaxLogicalDistance(intf_id, &mld);
3391 if (err != BCM_ERR_OK) {
3392 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3393 }
3394
3395 /* Initialize the API struct. */
3396 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
3397 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
3398 BCMOLT_FIELD_SET_PRESENT(&itu, itu_onu_params, ranging_time);
3399 BCMOLT_FIELD_SET(&onu_cfg.data, onu_cfg_data, itu, itu);
3400 #ifdef TEST_MODE
3401 // It is impossible to mock the setting of onu_cfg.data.onu_state because
3402 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
3403 // set the onu_cfg.data.onu_state. So a new stub function is created and address
3404 // of onu_cfg is passed. This is one-of case where we need to add test specific
3405 // code in production code.
3406 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
3407 #else
3408 /* Call API function. */
3409 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
3410 #endif
3411 if (err != BCM_ERR_OK) {
3412 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);
3413 return bcm_to_grpc_err(err, "Failed to retrieve ONU ranging time");
3414 }
3415
3416 if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_ACTIVE) {
3417 OPENOLT_LOG(ERROR, openolt_log_id, "ONU is not yet activated (PON %d, ONU id %d)\n", intf_id, onu_id);
3418 return bcm_to_grpc_err(BCM_ERR_PARM, "ONU is not yet activated\n");
3419 }
3420
3421 LDi = LOGICAL_DISTANCE(mld*1000, onu_cfg.data.itu.ranging_time, ONU_BIT_TRANSMISSION_DELAY);
3422 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance is %f, (PON %d, ONU id %d)\n", LDi, intf_id, onu_id);
3423 response->set_intf_id(intf_id);
3424 response->set_onu_id(onu_id);
3425 response->set_logical_onu_distance(LDi);
3426
3427 return Status::OK;
3428}
Burak Gurdag74e3ab82020-12-17 13:35:06 +00003429
3430Status GetOnuStatistics_(uint32_t intf_id, uint32_t onu_id, openolt::OnuStatistics* onu_stats) {
3431 bcmos_errno err;
3432
3433 err = get_onu_statistics((bcmolt_interface_id)intf_id, (bcmolt_onu_id)onu_id, onu_stats);
3434
3435 if (err != BCM_ERR_OK) {
3436 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));
3437 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of ONU statistics failed");
3438 }
3439
3440 OPENOLT_LOG(INFO, openolt_log_id, "retrieved ONU statistics for PON ID = %d, ONU ID = %d\n", (int)intf_id, (int)onu_id);
3441 return Status::OK;
3442}
3443
3444Status GetGemPortStatistics_(uint32_t intf_id, uint32_t gemport_id, openolt::GemPortStatistics* gemport_stats) {
3445 bcmos_errno err;
3446
3447 err = get_gemport_statistics((bcmolt_interface_id)intf_id, (bcmolt_gem_port_id)gemport_id, gemport_stats);
3448
3449 if (err != BCM_ERR_OK) {
3450 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));
3451 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of GEMPORT statistics failed");
3452 }
3453
3454 OPENOLT_LOG(INFO, openolt_log_id, "retrieved GEMPORT statistics for PON ID = %d, GEMPORT ID = %d\n", (int)intf_id, (int)gemport_id);
3455 return Status::OK;
3456}
Orhan Kupusogluec57af02021-05-12 12:38:17 +00003457
Akash Reddy Kankanaladec6e7e2025-05-22 09:49:28 +05303458Status GetPonPortStatistics_(uint32_t intf_id, common::PortStatistics* pon_stats) {
3459 bcmos_errno err;
3460 bcmolt_intf_ref intf_ref;
3461 intf_ref.intf_type = BCMOLT_INTERFACE_TYPE_PON;
3462 intf_ref.intf_id = intf_id;
3463
3464 err = get_port_statistics(intf_ref, pon_stats);
3465
3466 if (err != BCM_ERR_OK) {
3467 OPENOLT_LOG(ERROR, openolt_log_id, "retrieval of Pon port statistics failed - Intf ID = %u, err = %d - %s", intf_id, err, bcmos_strerror(err));
3468 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of Pon port statistics failed");
3469 }
3470
3471 OPENOLT_LOG(INFO, openolt_log_id, "retrieved Pon port statistics for Intf ID = %d\n", (int)intf_id);
3472 return Status::OK;
3473}
3474
3475Status GetNniPortStatistics_(uint32_t intf_id, common::PortStatistics* nni_stats) {
3476 bcmos_errno err;
3477 bcmolt_intf_ref intf_ref;
3478 intf_ref.intf_type = BCMOLT_INTERFACE_TYPE_NNI;
3479 intf_ref.intf_id = intf_id;
3480
3481 err = get_port_statistics(intf_ref, nni_stats);
3482
3483 if (err != BCM_ERR_OK) {
3484 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));
3485 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of Nni port statistics failed");
3486 }
3487
3488 OPENOLT_LOG(INFO, openolt_log_id, "retrieved Nni port statistics for Nni Port ID = %d\n", (int)intf_id);
3489 return Status::OK;
3490}
3491
3492Status GetAllocIdStatistics_(uint32_t intf_id, uint32_t alloc_id, openolt::OnuAllocIdStatistics* alloc_stats) {
3493 bcmos_errno err;
3494
3495 err = get_alloc_statistics((bcmolt_interface_id)intf_id, (bcmolt_alloc_id)alloc_id, alloc_stats);
3496
3497 if (err != BCM_ERR_OK) {
3498 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));
3499 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of ALLOC_ID statistics failed");
3500 }
3501
3502 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);
3503 return Status::OK;
3504}
3505
Orhan Kupusogluec57af02021-05-12 12:38:17 +00003506Status GetPonRxPower_(uint32_t intf_id, uint32_t onu_id, openolt::PonRxPowerData* response) {
3507 bcmos_errno err = BCM_ERR_OK;
3508
3509 // check the PON intf id
3510 if (intf_id >= MAX_SUPPORTED_PON) {
3511 err = BCM_ERR_PARM;
3512 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pon intf_id - intf_id: %d, onu_id: %d\n",
3513 intf_id, onu_id);
3514 return bcm_to_grpc_err(err, "invalid pon intf_id");
3515 }
3516
3517 bcmolt_onu_rssi_measurement onu_oper; /* declare main API struct */
3518 bcmolt_onu_key onu_key; /**< Object key. */
3519 onu_rssi_compltd_key key(intf_id, onu_id);
3520 Queue<onu_rssi_complete_result> queue;
3521
3522 OPENOLT_LOG(INFO, openolt_log_id, "GetPonRxPower - intf_id %d, onu_id %d\n", intf_id, onu_id);
3523
3524 onu_key.onu_id = onu_id;
3525 onu_key.pon_ni = intf_id;
3526 /* Initialize the API struct. */
3527 BCMOLT_OPER_INIT(&onu_oper, onu, rssi_measurement, onu_key);
3528 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
3529 if (err == BCM_ERR_OK) {
3530 // initialize map
3531 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3532 onu_rssi_compltd_map.insert({key, &queue});
3533 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3534 } else {
3535 OPENOLT_LOG(ERROR, openolt_log_id, "failed to measure rssi rx power - intf_id: %d, onu_id: %d, err = %s (%d): %s\n",
3536 intf_id, onu_id, bcmos_strerror(err), err, onu_oper.hdr.hdr.err_text);
3537 return bcm_to_grpc_err(err, "failed to measure rssi rx power");
3538 }
3539
3540 onu_rssi_complete_result completed{};
3541 if (!queue.pop(completed, ONU_RSSI_COMPLETE_WAIT_TIMEOUT)) {
3542 // invalidate the queue pointer
3543 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3544 onu_rssi_compltd_map[key] = NULL;
3545 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3546 err = BCM_ERR_TIMEOUT;
3547 OPENOLT_LOG(ERROR, openolt_log_id, "timeout waiting for RSSI Measurement Completed indication intf_id %d, onu_id %d\n",
3548 intf_id, onu_id);
3549 } else {
3550 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",
3551 completed.pon_intf_id, completed.onu_id, completed.status.c_str(), completed.reason, completed.rx_power_mean_dbm);
3552
3553 response->set_intf_id(completed.pon_intf_id);
3554 response->set_onu_id(completed.onu_id);
3555 response->set_status(completed.status);
3556 response->set_fail_reason(static_cast<::openolt::PonRxPowerData_RssiMeasurementFailReason>(completed.reason));
3557 response->set_rx_power_mean_dbm(completed.rx_power_mean_dbm);
3558 }
3559
3560 // Remove entry from map
3561 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3562 onu_rssi_compltd_map.erase(key);
3563 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3564
3565 if (err == BCM_ERR_OK) {
3566 return Status::OK;
3567 } else {
3568 return bcm_to_grpc_err(err, "timeout waiting for pon rssi measurement complete indication");
3569 }
3570}
nikesh.krishnan331d38c2023-04-06 03:24:53 +05303571
3572Status GetOnuInfo_(uint32_t intf_id, uint32_t onu_id, openolt::OnuInfo *response)
3573{
3574 bcmos_errno err = BCM_ERR_OK;
3575
3576 bcmolt_onu_state onu_state;
3577
3578 bcmolt_status losi;
3579 bcmolt_status lofi;
3580 bcmolt_status loami;
3581 err = get_gpon_onu_info((bcmolt_interface)intf_id, onu_id, &onu_state, &losi, &lofi, &loami);
3582
3583 if (err == BCM_ERR_OK)
3584 {
3585
3586 response->set_onu_id(onu_id);
3587 OPENOLT_LOG(DEBUG, openolt_log_id, "onu state %d\n", onu_state);
3588 OPENOLT_LOG(DEBUG, openolt_log_id, "losi %d\n", losi);
3589 OPENOLT_LOG(DEBUG, openolt_log_id, "lofi %d\n", lofi);
3590 OPENOLT_LOG(DEBUG, openolt_log_id, "loami %d\n", loami);
3591
3592 switch (onu_state)
3593 {
3594 case bcmolt_onu_state::BCMOLT_ONU_STATE_ACTIVE:
3595 response->set_state(openolt::OnuInfo_OnuState::OnuInfo_OnuState_ACTIVE);
3596 break;
3597 case bcmolt_onu_state::BCMOLT_ONU_STATE_INACTIVE:
3598 response->set_state(openolt::OnuInfo_OnuState::OnuInfo_OnuState_INACTIVE);
3599 break;
3600 case bcmolt_onu_state::BCMOLT_ONU_STATE_UNAWARE:
3601 response->set_state(openolt::OnuInfo_OnuState::OnuInfo_OnuState_UNKNOWN);
3602 break;
3603 case bcmolt_onu_state::BCMOLT_ONU_STATE_NOT_CONFIGURED:
3604 response->set_state(openolt::OnuInfo_OnuState::OnuInfo_OnuState_NOT_CONFIGURED);
3605 break;
3606 case bcmolt_onu_state::BCMOLT_ONU_STATE_DISABLED:
3607 response->set_state(openolt::OnuInfo_OnuState::OnuInfo_OnuState_DISABLED);
3608 break;
3609 }
3610 switch (losi)
3611 {
3612 case bcmolt_status::BCMOLT_STATUS_ON:
3613 response->set_losi(openolt::AlarmState::ON);
3614 break;
3615 case bcmolt_status::BCMOLT_STATUS_OFF:
3616 response->set_losi(openolt::AlarmState::OFF);
3617 break;
3618 }
3619
3620 switch (lofi)
3621 {
3622 case bcmolt_status::BCMOLT_STATUS_ON:
3623 response->set_lofi(openolt::AlarmState::ON);
3624 break;
3625 case bcmolt_status::BCMOLT_STATUS_OFF:
3626 response->set_lofi(openolt::AlarmState::OFF);
3627 break;
3628 }
3629
3630 switch (loami)
3631 {
3632 case bcmolt_status::BCMOLT_STATUS_ON:
3633 response->set_loami(openolt::AlarmState::ON);
3634 break;
3635 case bcmolt_status::BCMOLT_STATUS_OFF:
3636 response->set_loami(openolt::AlarmState::OFF);
3637 break;
3638 }
3639 return Status::OK;
3640 }
3641 else
3642 {
3643 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch Onu status, onu_id = %d, intf_id = %d, err = %s\n",
3644 onu_id, intf_id, bcmos_strerror(err));
3645 return bcm_to_grpc_err(err, "Failed to fetch Onu status");
3646 }
3647}
3648
3649Status GetPonInterfaceInfo_(uint32_t intf_id, openolt::PonIntfInfo *response)
3650{
3651 bcmos_errno err = BCM_ERR_OK;
3652
3653 bcmolt_status los_status;
3654 bcmolt_interface_state state;
3655 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
3656 OPENOLT_LOG(ERROR, openolt_log_id, "pon state %d\n",state);
3657 OPENOLT_LOG(ERROR, openolt_log_id, "pon los status %d\n", los_status);
3658
3659
3660 if (err == BCM_ERR_OK)
3661 {
3662 response->set_intf_id(intf_id) ;
3663 switch (los_status)
3664 {
3665 case bcmolt_status::BCMOLT_STATUS_ON:
3666
3667 response->set_los(openolt::AlarmState::ON);
3668 break;
3669 case bcmolt_status::BCMOLT_STATUS_OFF:
3670 response->set_los(openolt::AlarmState::OFF);
3671 break;
3672 }
3673
3674 switch (state)
3675 {
3676 case bcmolt_interface_state::BCMOLT_INTERFACE_STATE_ACTIVE_WORKING:
3677 response->set_state(openolt::PonIntfInfo_PonIntfState::PonIntfInfo_PonIntfState_ACTIVE_WORKING);
3678 break;
3679 case bcmolt_interface_state::BCMOLT_INTERFACE_STATE_ACTIVE_STANDBY:
3680 response->set_state(openolt::PonIntfInfo_PonIntfState::PonIntfInfo_PonIntfState_ACTIVE_STANDBY);
3681 break;
3682
3683 case bcmolt_interface_state::BCMOLT_INTERFACE_STATE_DISABLED:
3684 response->set_state(openolt::PonIntfInfo_PonIntfState::PonIntfInfo_PonIntfState_DISABLED);
3685 break;
3686
3687 case bcmolt_interface_state::BCMOLT_INTERFACE_STATE_INACTIVE:
3688
3689 response->set_state(openolt::PonIntfInfo_PonIntfState::PonIntfInfo_PonIntfState_INACTIVE);
3690 break;
3691 default:
3692 response->set_state(openolt::PonIntfInfo_PonIntfState::PonIntfInfo_PonIntfState_UNKNOWN);
3693 }
3694
3695 return Status::OK;
3696 }
3697 else
3698 {
3699 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch PON interface los status intf_id = %d, err = %s\n",
3700 intf_id, bcmos_strerror(err));
3701 return bcm_to_grpc_err(err, "Failed to fetch PON interface los status intf_id");
3702 }
3703}