blob: 65ce38a681a19a1cb73d1de48e5f49b998ccde5f [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);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080073static bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +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);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500212
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800213 char serial_number[OPENOLT_FIELD_LEN];
214 memset(serial_number, '\0', OPENOLT_FIELD_LEN);
215 openolt_read_sysinfo("Serial Number", serial_number);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000216 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device serial number %s\n", serial_number);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800217 device_info->set_device_serial_number(serial_number);
Burak Gurdag30db4822021-03-10 21:30:01 +0000218 device_info->set_previously_connected(state.previously_connected());
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800219
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700220 char device_id[OPENOLT_FIELD_LEN];
221 memset(device_id, '\0', OPENOLT_FIELD_LEN);
Humera Kouser6143c9e2020-06-17 22:37:31 +0530222
223 if (grpc_server_interface_name != NULL) {
224 if (get_intf_mac(grpc_server_interface_name, device_id, sizeof(device_id)) != NULL)
225 {
226 OPENOLT_LOG(INFO, openolt_log_id, "Fetched mac address %s of an interface %s\n", device_id, grpc_server_interface_name);
227 }
228 else
229 {
230 OPENOLT_LOG(ERROR, openolt_log_id, "Mac address of an interface %s is NULL\n", grpc_server_interface_name);
231 }
232 }
233 else
234 {
235 openolt_read_sysinfo("MAC", device_id);
236 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device mac address %s\n", device_id);
237 }
238
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700239 device_info->set_device_id(device_id);
Girish Gowdra252f4972020-09-07 21:24:01 -0700240 std::map<std::string, ::openolt::DeviceInfo::DeviceResourceRanges*> ranges;
Craig Lutgenb2601f02018-10-23 13:04:31 -0500241 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
242 std::string intf_technology = intf_technologies[intf_id];
Girish Gowdra252f4972020-09-07 21:24:01 -0700243 ::openolt::DeviceInfo::DeviceResourceRanges *range = ranges[intf_technology];
Craig Lutgenb2601f02018-10-23 13:04:31 -0500244 if(range == nullptr) {
245 range = device_info->add_ranges();
246 ranges[intf_technology] = range;
247 range->set_technology(intf_technology);
248
Girish Gowdra252f4972020-09-07 21:24:01 -0700249 ::openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
Craig Lutgenb2601f02018-10-23 13:04:31 -0500250
Girish Gowdra252f4972020-09-07 21:24:01 -0700251 pool = range->add_pools();
252 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
253 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
254 pool->set_start(ONU_ID_START);
255 pool->set_end(ONU_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500256
Girish Gowdra252f4972020-09-07 21:24:01 -0700257 pool = range->add_pools();
258 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
259 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
260 pool->set_start(ALLOC_ID_START);
Girish Gowdraeec0fc92021-05-12 15:37:55 -0700261 pool->set_end(ALLOC_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500262
Girish Gowdra252f4972020-09-07 21:24:01 -0700263 pool = range->add_pools();
264 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
265 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
266 pool->set_start(GEM_PORT_ID_START);
267 pool->set_end(GEM_PORT_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500268
Girish Gowdra252f4972020-09-07 21:24:01 -0700269 pool = range->add_pools();
270 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
271 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
272 pool->set_start(FLOW_ID_START);
273 pool->set_end(FLOW_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500274 }
275
276 range->add_intf_ids(intf_id);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500277 }
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400278
279 // FIXME: Once dependency problem is fixed
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500280 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400281 // device_info->set_onu_id_end(XGPON_NUM_OF_ONUS - 1);
282 // device_info->set_alloc_id_start(1024);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500283 // device_info->set_alloc_id_end(XGPON_NUM_OF_ALLOC_IDS * num_of_pon_ports ? - 1);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400284 // device_info->set_gemport_id_start(XGPON_MIN_BASE_SERVICE_PORT_ID);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500285 // device_info->set_gemport_id_end(XGPON_NUM_OF_GEM_PORT_IDS_PER_PON * num_of_pon_ports ? - 1);
286 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400287
288 return Status::OK;
289}
290
Thiyagarajan Subramani3e8bfd92021-04-26 15:07:14 +0530291void reset_pon_device(bcmolt_odid dev)
292{
293 bcmos_errno err;
294 bcmolt_device_reset oper;
295 bcmolt_device_key key = {.device_id = dev};
296
297 OPENOLT_LOG(INFO, openolt_log_id, "Reset PON device: %d\n", dev);
298
299 BCMOLT_OPER_INIT(&oper, device, reset, key);
300 err = bcmolt_oper_submit(dev_id, &oper.hdr);
301 if (err)
302 {
303 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to reset PON device(%d) failed, err = %s\n", dev, bcmos_strerror(err));
304 }else
305 {
306 OPENOLT_LOG(INFO, openolt_log_id, "Reset PON device(%d) success\n", dev);
307 }
308}
309
Shad Ansari627b5782018-08-13 22:49:32 +0000310Status Enable_(int argc, char *argv[]) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000311 bcmos_errno err;
312 bcmolt_host_init_parms init_parms = {};
313 init_parms.transport.type = BCM_HOST_API_CONN_LOCAL;
314 unsigned int failed_enable_device_cnt = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000315
Shad Ansariedef2132018-08-10 22:14:50 +0000316 if (!state.is_activated()) {
Shad Ansari627b5782018-08-13 22:49:32 +0000317
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500318 vendor_init();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000319 /* Initialize host subsystem */
320 err = bcmolt_host_init(&init_parms);
321 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500322 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to init OLT, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000323 return bcm_to_grpc_err(err, "Failed to init OLT");
324 }
325
326 bcmcli_session_parm mon_session_parm;
327 /* Create CLI session */
328 memset(&mon_session_parm, 0, sizeof(mon_session_parm));
329 mon_session_parm.get_prompt = openolt_cli_get_prompt_cb;
330 mon_session_parm.access_right = BCMCLI_ACCESS_ADMIN;
331 bcmos_errno rc = bcmcli_session_open(&mon_session_parm, &current_session);
332 BUG_ON(rc != BCM_ERR_OK);
333
334 /* API CLI */
335 bcm_openolt_api_cli_init(NULL, current_session);
336
337 /* Add quit command */
338 BCMCLI_MAKE_CMD_NOPARM(NULL, "quit", "Quit", bcm_cli_quit);
339
340 err = bcmolt_apiend_cli_init();
341 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500342 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to add apiend init, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000343 return bcm_to_grpc_err(err, "Failed to add apiend init");
344 }
345
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800346 bcmos_fastlock_init(&data_lock, 0);
Girish Gowdra252f4972020-09-07 21:24:01 -0700347 bcmos_fastlock_init(&acl_id_bitset_lock, 0);
348 bcmos_fastlock_init(&tm_sched_bitset_lock, 0);
349 bcmos_fastlock_init(&tm_qmp_bitset_lock, 0);
350 bcmos_fastlock_init(&flow_id_bitset_lock, 0);
351 bcmos_fastlock_init(&voltha_flow_to_device_flow_lock, 0);
Girish Gowdra96461052019-11-22 20:13:59 +0530352 bcmos_fastlock_init(&alloc_cfg_wait_lock, 0);
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +0530353 bcmos_fastlock_init(&gem_cfg_wait_lock, 0);
Girish Gowdra7a79dae2020-02-10 18:22:11 +0530354 bcmos_fastlock_init(&onu_deactivate_wait_lock, 0);
Girish Gowdra1935e6a2020-10-31 21:48:22 -0700355 bcmos_fastlock_init(&acl_packet_trap_handler_lock, 0);
Girish Gowdraeec0fc92021-05-12 15:37:55 -0700356 bcmos_fastlock_init(&symmetric_datapath_flow_id_lock, 0);
357 bcmos_fastlock_init(&pon_gem_to_onu_uni_map_lock, 0);
358
Girish Gowdra1935e6a2020-10-31 21:48:22 -0700359
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000360 OPENOLT_LOG(INFO, openolt_log_id, "Enable OLT - %s-%s\n", VENDOR_ID, MODEL_ID);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600361
Jason Huangbf45ffb2019-10-30 17:29:02 +0800362 //check BCM daemon is connected or not
363 Status status = check_connection();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000364 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800365 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000366 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800367 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000368 Status status = SubscribeIndication();
369 if (!status.ok()) {
370 OPENOLT_LOG(ERROR, openolt_log_id, "SubscribeIndication failed - %s : %s\n",
371 grpc_status_code_to_string(status.error_code()).c_str(),
372 status.error_message().c_str());
373 return status;
374 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800375
376 //check BAL state in initial stage
377 status = check_bal_ready();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000378 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800379 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000380 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800381 }
382
383 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000384 bcmos_errno err;
385 bcmolt_odid dev;
386 OPENOLT_LOG(INFO, openolt_log_id, "Enabling PON %d Devices ... \n", BCM_MAX_DEVS_PER_LINE_CARD);
387 for (dev = 0; dev < BCM_MAX_DEVS_PER_LINE_CARD; dev++) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400388 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000389 bcmolt_device_key dev_key = { };
390 dev_key.device_id = dev;
391 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
392 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Thiyagarajan Subramani4e62e172021-06-25 17:31:30 +0530393
Girish Gowdrab0337eb2022-03-25 16:44:21 -0700394 /* FIXME: Single Phoenix BAL patch is prepared for all three variants of Radisys OLT
395 * in which BCM_MAX_DEVS_PER_LINE_CARD macro need to be redefined as 1 incase of
396 * "rlt-1600g-w" and "rlt-1600x-w", till then this workaround is required.*/
Thiyagarajan Subramani4e62e172021-06-25 17:31:30 +0530397 if (dev == 1 && (MODEL_ID == "rlt-1600g-w" || MODEL_ID == "rlt-1600x-w")) {
Girish Gowdrab0337eb2022-03-25 16:44:21 -0700398 continue;
399 }
Thiyagarajan Subramani4e62e172021-06-25 17:31:30 +0530400
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000401 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
Jason Huangbf45ffb2019-10-30 17:29:02 +0800402 if (err == BCM_ERR_NOT_CONNECTED) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000403 bcmolt_device_key key = {.device_id = dev};
404 bcmolt_device_connect oper;
405 BCMOLT_OPER_INIT(&oper, device, connect, key);
Thiyagarajan Subramani3e8bfd92021-04-26 15:07:14 +0530406
Girish Gowdrab0337eb2022-03-25 16:44:21 -0700407 /* BAL saves current state into dram_tune soc file and when dev_mgmt_daemon restarts
408 * it retains config from soc file. If openolt agent try to connect device without
409 * device reset device initialization fails hence doing device reset here. */
Thiyagarajan Subramani3e8bfd92021-04-26 15:07:14 +0530410 reset_pon_device(dev);
Girish Gowdrab0337eb2022-03-25 16:44:21 -0700411 bcmolt_system_mode sm;
412 #ifdef DYNAMIC_PON_TRX_SUPPORT
413 auto sm_res = ponTrx.get_mac_system_mode(dev, ponTrx.get_sfp_presence_data());
414 if (!sm_res.second) {
415 OPENOLT_LOG(ERROR, openolt_log_id, "could not read mac system mode. dev_id = %d\n", dev);
416 continue;
417 }
418 sm = sm_res.first;
419 #else
420 sm = DEFAULT_MAC_SYSTEM_MODE;
421 #endif
422 BCMOLT_MSG_FIELD_SET (&oper, system_mode, sm);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000423 if (MODEL_ID == "asfvolt16") {
424 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000425 } else if (MODEL_ID == "asgvolt64") {
426 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
427 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
Thiyagarajan Subramani4e62e172021-06-25 17:31:30 +0530428 } else if (MODEL_ID == "rlt-3200g-w" || MODEL_ID == "rlt-1600g-w") {
Thiyagarajan Subramani3e8bfd92021-04-26 15:07:14 +0530429 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_NONE);
430 if(dev == 1) {
431 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
432 }
433 BCMOLT_MSG_FIELD_SET (&oper, ras_ddr_mode, BCMOLT_RAS_DDR_USAGE_MODE_TWO_DDRS);
434 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
Thiyagarajan Subramani4e62e172021-06-25 17:31:30 +0530435 } else if (MODEL_ID == "rlt-1600x-w") {
436 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_NONE);
437 BCMOLT_MSG_FIELD_SET (&oper, ras_ddr_mode, BCMOLT_RAS_DDR_USAGE_MODE_TWO_DDRS);
438 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
Arthur Syu094df162022-04-21 17:50:06 +0800439 } else if (MODEL_ID == "sda3016ss") {
440 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_12_P_5_G);
441 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_TWO_TO_ONE);
442 BCMOLT_MSG_FIELD_SET (&oper, ras_ddr_mode, BCMOLT_RAS_DDR_USAGE_MODE_TWO_DDRS);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000443 }
444 err = bcmolt_oper_submit(dev_id, &oper.hdr);
445 if (err) {
446 failed_enable_device_cnt ++;
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500447 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 +0000448 if (failed_enable_device_cnt == BCM_MAX_DEVS_PER_LINE_CARD) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500449 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 +0000450 return Status(grpc::StatusCode::INTERNAL, "Failed to activate all PON ports");
451 }
452 }
Girish Gowdra72bb4652022-01-18 17:04:30 -0800453 bcmos_usleep(MAC_DEVICE_ACTIVATION_DELAY);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000454 }
455 else {
Thiyagarajan Subramani4e62e172021-06-25 17:31:30 +0530456 OPENOLT_LOG(WARNING, openolt_log_id, "PON device %d already connected\n", dev);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000457 state.activate();
458 }
459 }
460 init_stats();
Shad Ansari627b5782018-08-13 22:49:32 +0000461 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000462 }
Shad Ansariedef2132018-08-10 22:14:50 +0000463
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000464 /* Start CLI */
465 OPENOLT_LOG(INFO, def_log_id, "Starting CLI\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400466 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000467 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400468}
469
470Status Disable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400471 //In the earlier implementation Disabling olt is done by disabling the NNI port associated with that.
472 //In inband scenario instead of using management interface to establish connection with adapter ,NNI interface will be used.
473 //Disabling NNI port on olt disable causes connection loss between adapter and agent.
474 //To overcome this disable is implemented by disabling all the PON ports
475 //associated with the device so as to support both in-band
476 //and out of band scenarios.
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400477
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400478 Status status;
479 int failedCount = 0;
Girish Gowdrae1db2952021-05-04 00:16:54 -0700480 OPENOLT_LOG(INFO, openolt_log_id, "Received disable OLT\n");
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400481 for (int i = 0; i < NumPonIf_(); i++) {
482 status = DisablePonIf_(i);
483 if (!status.ok()) {
484 failedCount+=1;
485 BCM_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", i);
486 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400487 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400488 if (failedCount == 0) {
489 state.deactivate();
Girish Gowdra252f4972020-09-07 21:24:01 -0700490 ::openolt::Indication ind;
491 ::openolt::OltIndication* olt_ind = new ::openolt::OltIndication;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400492 olt_ind->set_oper_state("down");
493 ind.set_allocated_olt_ind(olt_ind);
494 BCM_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
495 oltIndQ.push(ind);
496 return Status::OK;
497 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000498 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400499 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to disable olt ,all the PON ports are still in enabled state");
500 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400501
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400502 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 -0400503}
504
505Status Reenable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400506 Status status;
507 int failedCount = 0;
508 for (int i = 0; i < NumPonIf_(); i++) {
509 status = EnablePonIf_(i);
510 if (!status.ok()) {
511 failedCount+=1;
512 BCM_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", i);
513 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400514 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000515 if (failedCount == 0) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400516 state.activate();
Girish Gowdra252f4972020-09-07 21:24:01 -0700517 ::openolt::Indication ind;
518 ::openolt::OltIndication* olt_ind = new ::openolt::OltIndication;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400519 olt_ind->set_oper_state("up");
520 ind.set_allocated_olt_ind(olt_ind);
521 BCM_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
522 oltIndQ.push(ind);
523 return Status::OK;
524 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000525 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400526 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to re-enable olt ,all the PON ports are still in disabled state");
527 }
528 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 +0000529}
530
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000531inline uint64_t get_flow_status(uint16_t flow_id, uint16_t flow_type, uint16_t data_id) {
532 bcmos_errno err;
533 bcmolt_flow_key flow_key;
534 bcmolt_flow_cfg flow_cfg;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400535
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000536 flow_key.flow_id = flow_id;
537 flow_key.flow_type = (bcmolt_flow_type)flow_type;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400538
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000539 BCMOLT_CFG_INIT(&flow_cfg, flow, flow_key);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400540
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000541 switch (data_id) {
542 case ONU_ID: //onu_id
543 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, onu_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500544 #ifdef TEST_MODE
545 // It is impossible to mock the setting of flow_cfg.data.state because
546 // the actual bcmolt_cfg_get passes the address of flow_cfg.hdr and we cannot
547 // set the flow_cfg.data. So a new stub function is created and address
548 // of flow_cfg is passed. This is one-of case where we need to add test specific
549 // code in production code.
550 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
551 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000552 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500553 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000554 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700555 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 +0000556 return err;
557 }
558 return flow_cfg.data.onu_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400559 case FLOW_TYPE:
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500560 #ifdef TEST_MODE
561 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
562 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000563 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500564 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000565 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700566 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 +0000567 return err;
568 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400569 return flow_cfg.key.flow_type;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000570 case SVC_PORT_ID: //svc_port_id
571 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, svc_port_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500572 #ifdef TEST_MODE
573 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
574 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000575 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500576 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000577 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700578 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 +0000579 return err;
580 }
581 return flow_cfg.data.svc_port_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400582 case PRIORITY:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000583 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, priority);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500584 #ifdef TEST_MODE
585 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
586 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000587 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500588 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000589 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700590 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 +0000591 return err;
592 }
593 return flow_cfg.data.priority;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400594 case COOKIE: //cookie
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000595 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, cookie);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500596 #ifdef TEST_MODE
597 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
598 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000599 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500600 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000601 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700602 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 +0000603 return err;
604 }
605 return flow_cfg.data.cookie;
606 case INGRESS_INTF_TYPE: //ingress intf_type
607 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500608 #ifdef TEST_MODE
609 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
610 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000611 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500612 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000613 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700614 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 +0000615 return err;
616 }
617 return flow_cfg.data.ingress_intf.intf_type;
618 case EGRESS_INTF_TYPE: //egress intf_type
619 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500620 #ifdef TEST_MODE
621 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
622 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000623 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500624 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000625 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700626 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 +0000627 return err;
628 }
629 return flow_cfg.data.egress_intf.intf_type;
630 case INGRESS_INTF_ID: //ingress intf_id
631 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500632 #ifdef TEST_MODE
633 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
634 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000635 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500636 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000637 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700638 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 +0000639 return err;
640 }
641 return flow_cfg.data.ingress_intf.intf_id;
642 case EGRESS_INTF_ID: //egress intf_id
643 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500644 #ifdef TEST_MODE
645 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
646 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000647 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500648 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000649 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700650 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 +0000651 return err;
652 }
653 return flow_cfg.data.egress_intf.intf_id;
654 case CLASSIFIER_O_VID:
655 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500656 #ifdef TEST_MODE
657 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
658 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000659 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500660 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000661 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700662 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 +0000663 return err;
664 }
665 return flow_cfg.data.classifier.o_vid;
666 case CLASSIFIER_O_PBITS:
667 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500668 #ifdef TEST_MODE
669 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
670 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000671 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500672 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000673 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700674 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 +0000675 return err;
676 }
677 return flow_cfg.data.classifier.o_pbits;
678 case CLASSIFIER_I_VID:
679 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500680 #ifdef TEST_MODE
681 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
682 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000683 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500684 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000685 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700686 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 +0000687 return err;
688 }
689 return flow_cfg.data.classifier.i_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400690 case CLASSIFIER_I_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000691 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500692 #ifdef TEST_MODE
693 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
694 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000695 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500696 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000697 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700698 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 +0000699 return err;
700 }
701 return flow_cfg.data.classifier.i_pbits;
702 case CLASSIFIER_ETHER_TYPE:
703 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500704 #ifdef TEST_MODE
705 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
706 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000707 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500708 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000709 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700710 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 +0000711 return err;
712 }
713 return flow_cfg.data.classifier.ether_type;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400714 case CLASSIFIER_IP_PROTO:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000715 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500716 #ifdef TEST_MODE
717 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
718 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000719 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500720 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000721 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700722 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 +0000723 return err;
724 }
725 return flow_cfg.data.classifier.ip_proto;
726 case CLASSIFIER_SRC_PORT:
727 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500728 #ifdef TEST_MODE
729 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
730 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000731 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500732 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000733 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700734 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 +0000735 return err;
736 }
737 return flow_cfg.data.classifier.src_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400738 case CLASSIFIER_DST_PORT:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000739 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500740 #ifdef TEST_MODE
741 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
742 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000743 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500744 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000745 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700746 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 +0000747 return err;
748 }
749 return flow_cfg.data.classifier.dst_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400750 case CLASSIFIER_PKT_TAG_TYPE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000751 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500752 #ifdef TEST_MODE
753 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
754 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000755 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500756 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000757 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700758 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 +0000759 return err;
760 }
761 return flow_cfg.data.classifier.pkt_tag_type;
762 case EGRESS_QOS_TYPE:
763 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500764 #ifdef TEST_MODE
765 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
766 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000767 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500768 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000769 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700770 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 +0000771 return err;
772 }
773 return flow_cfg.data.egress_qos.type;
774 case EGRESS_QOS_QUEUE_ID:
775 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500776 #ifdef TEST_MODE
777 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
778 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000779 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500780 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000781 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700782 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 +0000783 return err;
784 }
785 switch (flow_cfg.data.egress_qos.type) {
786 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE:
787 return flow_cfg.data.egress_qos.u.fixed_queue.queue_id;
788 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE:
789 return flow_cfg.data.egress_qos.u.tc_to_queue.tc_to_queue_id;
790 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC:
791 return flow_cfg.data.egress_qos.u.pbit_to_tc.tc_to_queue_id;
792 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE:
793 return flow_cfg.data.egress_qos.u.priority_to_queue.tm_q_set_id;
794 case BCMOLT_EGRESS_QOS_TYPE_NONE:
795 default:
796 return -1;
797 }
798 case EGRESS_QOS_TM_SCHED_ID:
799 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500800 #ifdef TEST_MODE
801 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
802 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000803 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500804 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000805 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700806 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 +0000807 return err;
808 }
809 return flow_cfg.data.egress_qos.tm_sched.id;
810 case ACTION_CMDS_BITMASK:
811 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500812 #ifdef TEST_MODE
813 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
814 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000815 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500816 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000817 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700818 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 +0000819 return err;
820 }
821 return flow_cfg.data.action.cmds_bitmask;
822 case ACTION_O_VID:
823 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500824 #ifdef TEST_MODE
825 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
826 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000827 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500828 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000829 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700830 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 +0000831 return err;
832 }
833 return flow_cfg.data.action.o_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400834 case ACTION_O_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000835 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500836 #ifdef TEST_MODE
837 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
838 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000839 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500840 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000841 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700842 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 +0000843 return err;
844 }
845 return flow_cfg.data.action.o_pbits;
846 case ACTION_I_VID:
847 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500848 #ifdef TEST_MODE
849 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
850 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000851 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500852 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000853 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700854 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 +0000855 return err;
856 }
857 return flow_cfg.data.action.i_vid;
858 case ACTION_I_PBITS:
859 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500860 #ifdef TEST_MODE
861 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
862 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000863 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500864 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000865 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700866 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 +0000867 return err;
868 }
869 return flow_cfg.data.action.i_pbits;
870 case STATE:
871 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, state);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500872 #ifdef TEST_MODE
873 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
874 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000875 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500876 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000877 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700878 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 +0000879 return err;
880 }
881 return flow_cfg.data.state;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000882 case GROUP_ID:
883 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, group_id);
884 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
885 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700886 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 +0000887 return err;
888 }
889 return flow_cfg.data.group_id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000890 default:
891 return BCM_ERR_INTERNAL;
892 }
893
894 return err;
895}
896
897Status EnablePonIf_(uint32_t intf_id) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400898 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000899 bcmolt_pon_interface_cfg interface_obj;
900 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
901 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
902 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530903 bcmolt_status los_status;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000904
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530905 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000906 if (err == BCM_ERR_OK) {
907 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800908 OPENOLT_LOG(WARNING, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000909 return Status::OK;
910 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400911 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000912 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
913 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
914 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
915 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.interval, 5000);
916 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.onu_post_discovery_mode,
Girish Gowdra24297032020-03-23 12:32:37 -0700917 BCMOLT_ONU_POST_DISCOVERY_MODE_NONE);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000918 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.los, true);
919 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.onu_alarms, true);
920 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.tiwi, true);
921 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.ack_timeout, true);
922 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.sfi, true);
923 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.loki, true);
Burak Gurdag5e587792020-05-06 14:58:02 +0000924
925 // On GPON, power level mode is not set to its default value (i.e. 0) as documented in Broadcom documentation.
926 // 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 +0800927 std::string intf_technology = intf_technologies[intf_id];
928 if (intf_technology == "GPON") {
Burak Gurdag5e587792020-05-06 14:58:02 +0000929 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.pls_maximum_allocation_size, BCMOLT_PON_POWER_LEVEL_PLS_MAXIMUM_ALLOCATION_SIZE_DEFAULT);
930 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.mode, BCMOLT_PON_POWER_LEVEL_MODE_DEFAULT);
Shivanagouda Malaginahalli05bf9d42024-03-16 13:36:17 +0530931 /* PON gpon itu threshold default values for LOSi, LOFi and LOAMi are
932 configured as 4, 4 and 3 respectively. These values are suppressing
933 onu down indication from BAL.
934 To fix this problem all thresholds for LOSi, LOFi and LOAMi are
935 configured with 14. After this configuration BAL started sending
936 onu down indication.
937 */
938 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.onu_alarms_thresholds.losi, 14);
939 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.onu_alarms_thresholds.lofi, 14);
940 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.onu_alarms_thresholds.loami, 14);
Burak Gurdag5e587792020-05-06 14:58:02 +0000941 }
942
Girish Gowdrab0337eb2022-03-25 16:44:21 -0700943 // TODO: Currently the PON Type is set automatically when the MAC System Mode is set. But it could be explicitely set here again.
944 // The data for the PON type is availabe in the PonTrx object (check trx_data)
945
kesavandc1f2db92020-08-31 15:32:06 +0530946 //Enable AES Encryption
947 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.key_exchange, BCMOLT_CONTROL_STATE_ENABLE);
948 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.authentication, BCMOLT_CONTROL_STATE_ENABLE);
949 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 +0530950 /* PON LOS wait time is set to 500ms, so that ONU LOS will not be seen
951 before PON LOS during manual fiber pull or fiber cut scenarios.
952 */
953 BCMOLT_MSG_FIELD_SET(&interface_obj, los_wait_timeout, 500);
kesavandc1f2db92020-08-31 15:32:06 +0530954
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000955 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
956 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
957
958 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
959 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500960 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 +0000961 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
962 }
963 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
964 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500965 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 +0000966 return bcm_to_grpc_err(err, "Failed to enable PON interface");
967 }
968 else {
969 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
970 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
971 CreateDefaultSched(intf_id, downstream);
972 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400973 }
974
975 return Status::OK;
976}
977
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500978Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000979 bcmos_errno err;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400980 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000981 bcmolt_device_key dev_key = { };
982 bcmolt_olt_cfg olt_cfg = { };
983 bcmolt_olt_key olt_key = { };
984 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
985 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500986
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000987 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
988 topo.topology_maps.arr = &topo_map[0];
989 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
990 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
991 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400992 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000993 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400994 #ifdef TEST_MODE
995 // It is impossible to mock the setting of olt_cfg.data.bal_state because
996 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
997 // set the olt_cfg.data.topology. So a new stub function is created and address
998 // of olt_cfg is passed. This is one-of case where we need to test add specific
999 // code in production code.
1000 err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
1001 #else
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001002 err = bcmolt_cfg_get_mult_retry(dev_id, &olt_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001003 #endif
1004 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001005 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 +00001006 return bcm_to_grpc_err(err, "cfg: Failed to query OLT topology");
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001007 }
1008
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001009 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
1010 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001011
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001012 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
1013 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001014 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001015
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001016 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
1017 num_of_nni_ports,
1018 num_of_pon_ports,
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001019 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001020
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001021 uint32_t num_failed_cfg_gets = 0;
Jason Huang09b73ea2020-01-08 17:52:05 +08001022 static std::string openolt_version = firmware_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001023 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
1024 dev_key.device_id = devid;
1025 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
1026 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
1027 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
1028 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001029 err = bcmolt_cfg_get_mult_retry(dev_id, &dev_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001030 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001031 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 +00001032 num_failed_cfg_gets++;
1033 continue;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001034 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001035
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001036 std::string bal_version;
1037 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
1038 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
1039 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
Jason Huang09b73ea2020-01-08 17:52:05 +08001040 firmware_version = "BAL." + bal_version + "__" + openolt_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001041
1042 switch(dev_cfg.data.system_mode) {
1043 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
1044 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
1045 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
1046 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
1047 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
1048 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
1049 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
1050 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
1051 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
1052 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 +08001053 case 38:
1054 board_technology = "XGS-PON";
1055 FILL_ARRAY2(intf_technologies,devid*16,(devid+1)*16,"XGS-PON");
1056 FILL_ARRAY2(intf_technologies,devid*16+1,(devid+1)*16+1,"GPON");
1057 break;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001058 }
1059
1060 switch(dev_cfg.data.chip_family) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001061 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X: chip_family = "Maple"; break;
1062 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X: chip_family = "Aspen"; break;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001063 }
1064
Jason Huang09b73ea2020-01-08 17:52:05 +08001065 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s, family: %s, board_technology: %s\n",
1066 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 +00001067
1068 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001069 }
1070
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001071 /* 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 +00001072 only the devices that retured success*/
1073 if (num_failed_cfg_gets == BCM_MAX_DEVS_PER_LINE_CARD) {
1074 OPENOLT_LOG(ERROR, openolt_log_id, "device: Query of all the devices failed\n");
1075 return bcm_to_grpc_err(err, "device: All devices failed query");
1076 }
1077
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001078 return Status::OK;
1079}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001080
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001081Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001082 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001083 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
1084 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
1085 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001086
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001087 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001088 if (err == BCM_ERR_OK) {
1089 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001090 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001091 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1092 CreateDefaultSched(intf_id, upstream);
1093 CreateDefaultQueue(intf_id, upstream);
1094 return Status::OK;
1095 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1096 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
1097 return Status::OK;
1098 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001099 }
1100
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001101 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
1102 if (set_state) {
1103 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1104 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1105 } else {
1106 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1107 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1108 }
1109 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
1110 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001111 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err = %s\n",
1112 (set_state)?"enable":"disable", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001113 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
1114 }
1115 else {
1116 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
1117 if (set_state) {
1118 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1119 CreateDefaultSched(intf_id, upstream);
1120 CreateDefaultQueue(intf_id, upstream);
1121 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001122 }
1123
1124 return Status::OK;
1125}
1126
Elia Battiston869a5de2022-02-08 11:40:58 +01001127uint32_t GetNniSpeed_(uint32_t intf_id) {
1128 bcmos_errno err = BCM_ERR_OK;
1129
1130 uint32_t speed;
1131 err = get_nni_interface_speed((bcmolt_interface)intf_id, &speed);
1132 if (err != BCM_ERR_OK) {
1133 OPENOLT_LOG(WARNING, openolt_log_id, "Failed to read speed of NNI interface: %d\n", intf_id);
1134 return 0; //This will cause the adapter to use the default speed value
1135 }
1136
1137 return speed;
1138}
1139
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001140Status DisablePonIf_(uint32_t intf_id) {
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001141 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001142 bcmolt_pon_interface_cfg interface_obj;
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001143 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1144 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001145
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001146 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
Girish Gowdrae1db2952021-05-04 00:16:54 -07001147 BCMOLT_MSG_FIELD_GET(&interface_obj, state);
1148
1149 err = bcmolt_cfg_get(dev_id, &interface_obj.hdr);
1150 if (err != BCM_ERR_OK) {
1151 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);
1152 return bcm_to_grpc_err(err, "Failed to fetch pon port state");
1153 }
1154 if (interface_obj.data.state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1155 OPENOLT_LOG(INFO, openolt_log_id, "PON Interface already inactive, PON interface %d\n", intf_id);
1156 return Status::OK;
1157 }
1158
1159 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001160 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1161 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_DISABLE);
1162
1163 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1164 if (err != BCM_ERR_OK) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07001165 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 -05001166 return bcm_to_grpc_err(err, "Failed to disable discovery of onu");
1167 }
1168
1169 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1170 operation, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1171
1172 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1173 if (err != BCM_ERR_OK) {
1174 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 -04001175 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001176 }
1177
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001178 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled PON interface: %d\n", intf_id);
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001179 return Status::OK;
1180}
1181
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001182Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
kesavandc1f2db92020-08-31 15:32:06 +05301183 const char *vendor_id, const char *vendor_specific, uint32_t pir, bool omcc_encryption_mode) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001184 bcmos_errno err = BCM_ERR_OK;
1185 bcmolt_onu_cfg onu_cfg;
1186 bcmolt_onu_key onu_key;
Shivanagouda Malaginahallie707d612023-08-22 10:40:25 +00001187 bcmolt_serial_number serial_number = {}; /**< ONU serial number */
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001188 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001189
Girish Gowdra24297032020-03-23 12:32:37 -07001190 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1191 bcmolt_onu_state onu_state;
1192
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001193 onu_key.onu_id = onu_id;
1194 onu_key.pon_ni = intf_id;
1195 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1196 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Girish Gowdra24297032020-03-23 12:32:37 -07001197#ifdef TEST_MODE
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001198 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1199 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1200 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1201 // of onu_cfg is passed. This is one-of case where we need to add test specific
1202 // code in production code.
1203 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Girish Gowdra24297032020-03-23 12:32:37 -07001204#else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001205 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Girish Gowdra24297032020-03-23 12:32:37 -07001206#endif
1207 OPENOLT_LOG(INFO, openolt_log_id, "Activate ONU : old state = %d, current state = %d\n",
1208 onu_cfg.data.onu_old_state, onu_cfg.data.onu_state);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001209 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001210 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) {
1211 OPENOLT_LOG(INFO, openolt_log_id, "ONU is already in ACTIVE state, \
1212not processing this request for pon_intf=%d onu_id=%d\n", intf_id, onu_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001213 return Status::OK;
Girish Gowdra24297032020-03-23 12:32:37 -07001214 } else if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_NOT_CONFIGURED &&
1215 onu_cfg.data.onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1216 // We need the ONU to be in NOT_CONFIGURED or INACTIVE state to further process the request
1217 OPENOLT_LOG(ERROR, openolt_log_id, "ONU in an invalid state to process the request, \
1218state=%d pon_intf=%d onu_id=%d\n", onu_cfg.data.onu_state, intf_id, onu_id);
1219 return bcm_to_grpc_err(err, "Failed to activate ONU, invalid ONU state");
1220 }
1221 } else {
1222 // This should never happen. BAL GET should succeed for non-existant ONUs too. The state of such ONUs will be NOT_CONFIGURED
1223 OPENOLT_LOG(ERROR, openolt_log_id, "ONU state query failed pon_intf=%d onu_id=%d\n", intf_id, onu_id);
1224 return bcm_to_grpc_err(err, "onu get failed");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001225 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001226
Girish Gowdra24297032020-03-23 12:32:37 -07001227 // If the ONU is not configured at all we need to first configure it
1228 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_NOT_CONFIGURED) {
1229 OPENOLT_LOG(INFO, openolt_log_id, "Configuring ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001230vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Girish Gowdra24297032020-03-23 12:32:37 -07001231 vendor_specific_to_str(vendor_specific).c_str(), pir);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001232
Girish Gowdra24297032020-03-23 12:32:37 -07001233 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1234 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
Shivanagouda Malaginahallie707d612023-08-22 10:40:25 +00001235
Girish Gowdra24297032020-03-23 12:32:37 -07001236 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1237 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1238 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1239 /*set burst and data profiles to fec disabled*/
Arthur Syu094df162022-04-21 17:50:06 +08001240 std::string intf_technology = intf_technologies[intf_id];
1241 if (intf_technology == "XGS-PON") {
Girish Gowdra24297032020-03-23 12:32:37 -07001242 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1243 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
Arthur Syu094df162022-04-21 17:50:06 +08001244 } else if (intf_technology == "GPON") {
Girish Gowdra24297032020-03-23 12:32:37 -07001245 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1246 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1247 }
1248 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1249 if (err != BCM_ERR_OK) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07001250 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 -07001251 return bcm_to_grpc_err(err, "Failed to configure ONU");
1252 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001253 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001254
Burak Gurdaga0523592021-02-24 15:17:47 +00001255// TODO: MOVE THIS TO A NEW METHOD
kesavandc1f2db92020-08-31 15:32:06 +05301256 if (omcc_encryption_mode == true) {
1257 // set the encryption mode for omci port id
1258 bcmolt_itupon_gem_cfg gem_cfg;
1259 bcmolt_itupon_gem_key key = {};
1260 bcmolt_gem_port_configuration configuration = {};
1261 key.pon_ni = intf_id;
1262 key.gem_port_id = onu_id;
1263 bcmolt_control_state encryption_mode;
1264 encryption_mode = BCMOLT_CONTROL_STATE_ENABLE;
1265 BCMOLT_CFG_INIT(&gem_cfg, itupon_gem, key);
1266 BCMOLT_FIELD_SET(&gem_cfg.data, itupon_gem_cfg_data, encryption_mode, encryption_mode);
1267 err = bcmolt_cfg_set(dev_id, &gem_cfg.hdr);
1268 if(err != BCM_ERR_OK) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07001269 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 +05301270 return bcm_to_grpc_err(err, "Access_Control set ITU PON OMCI Gem port failed");
1271 }
1272 }
Girish Gowdra24297032020-03-23 12:32:37 -07001273 // Now that the ONU is configured, move the ONU to ACTIVE state
1274 memset(&onu_cfg, 0, sizeof(bcmolt_onu_cfg));
1275 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1276 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1277 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
1278 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
1279 onu_state, BCMOLT_ONU_OPERATION_ACTIVE);
1280 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001281 if (err != BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001282 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 +00001283 return bcm_to_grpc_err(err, "Failed to activate ONU");
1284 }
Girish Gowdra24297032020-03-23 12:32:37 -07001285 // ONU will eventually get activated after we have submitted the operation request. The adapter will receive an asynchronous
1286 // ONU_ACTIVATION_COMPLETED_INDICATION
1287
1288 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 +00001289
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001290 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001291}
1292
Jonathan Davis70c21812018-07-19 15:32:10 -04001293Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1294 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001295 bcmos_errno err = BCM_ERR_OK;
1296 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1297 bcmolt_onu_cfg onu_cfg;
1298 bcmolt_onu_key onu_key; /**< Object key. */
1299 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001300
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001301 onu_key.onu_id = onu_id;
1302 onu_key.pon_ni = intf_id;
1303 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1304 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1305 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301306 onu_state = onu_cfg.data.onu_state;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001307 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001308 switch (onu_state) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001309 case BCMOLT_ONU_STATE_ACTIVE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001310 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001311 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001312 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1313 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1314 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001315 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 +00001316 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1317 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301318 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 +00001319 break;
1320 }
Girish Gowdra72cbee92021-11-05 15:16:18 -07001321 } else {
1322 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to deactivate ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
1323 return bcm_to_grpc_err(err, "Failed to get onu config");
Jonathan Davis70c21812018-07-19 15:32:10 -04001324 }
1325
1326 return Status::OK;
1327}
1328
1329Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001330 const char *vendor_id, const char *vendor_specific) {
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301331 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301332 bcmolt_onu_state onu_state;
Girish Gowdra72cbee92021-11-05 15:16:18 -07001333 Status st;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001334
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001335 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 -05001336 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1337
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001338 // Need to deactivate before removing it (BAL rules)
Girish Gowdra72cbee92021-11-05 15:16:18 -07001339 st = DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
1340 if (st.error_code() != grpc::StatusCode::OK) {
1341 return st;
1342 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301343
Girish Gowdra72cbee92021-11-05 15:16:18 -07001344 err = get_onu_state((bcmolt_interface)intf_id, onu_id, &onu_state);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301345 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001346 if (onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1347 OPENOLT_LOG(INFO, openolt_log_id, "waiting for onu deactivate complete response: intf_id=%d, onu_id=%d\n",
1348 intf_id, onu_id);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301349 err = wait_for_onu_deactivate_complete(intf_id, onu_id);
1350 if (err) {
1351 OPENOLT_LOG(ERROR, openolt_log_id, "failed to delete onu intf_id %d, onu_id %d\n",
1352 intf_id, onu_id);
1353 return bcm_to_grpc_err(err, "Failed to delete ONU");
1354 }
1355 }
Girish Gowdra24297032020-03-23 12:32:37 -07001356 else {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301357 OPENOLT_LOG(INFO, openolt_log_id, "Onu is Inactive, onu_id: %d, not waiting for onu deactivate complete response\n",
1358 intf_id);
1359 }
1360 }
1361 else {
1362 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch Onu status, onu_id = %d, intf_id = %d, err = %s\n",
1363 onu_id, intf_id, bcmos_strerror(err));
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301364 return bcm_to_grpc_err(err, "Failed to delete ONU");
1365 }
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001366
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001367 bcmolt_onu_cfg cfg_obj;
1368 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001369
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001370 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 -04001371 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001372
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001373 key.onu_id = onu_id;
1374 key.pon_ni = intf_id;
1375 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001376
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301377 err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001378 if (err != BCM_ERR_OK)
1379 {
Girish Gowdra72cbee92021-11-05 15:16:18 -07001380 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 -04001381 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1382 }
1383
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301384 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 +00001385 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001386}
1387
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001388#define MAX_CHAR_LENGTH 20
1389#define MAX_OMCI_MSG_LENGTH 44
1390Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001391 bcmolt_bin_str buf = {};
1392 bcmolt_onu_cpu_packets omci_cpu_packets;
1393 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001394
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001395 key.pon_ni = intf_id;
1396 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001397
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001398 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1399 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1400 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001401
1402 // ???
1403 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1404 buf.len = MAX_OMCI_MSG_LENGTH;
1405 } else {
1406 buf.len = pkt.size()/2;
1407 }
1408
1409 /* Send the OMCI packet using the BAL remote proxy API */
1410 uint16_t idx1 = 0;
1411 uint16_t idx2 = 0;
1412 uint8_t arraySend[buf.len];
1413 char str1[MAX_CHAR_LENGTH];
1414 char str2[MAX_CHAR_LENGTH];
1415 memset(&arraySend, 0, buf.len);
1416
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001417 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1418 sprintf(str1,"%c", pkt[idx1]);
1419 sprintf(str2,"%c", pkt[++idx1]);
1420 strcat(str1,str2);
1421 arraySend[idx2] = strtol(str1, NULL, 16);
1422 }
1423
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001424 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1425 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001426
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001427 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1428 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1429 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001430
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001431 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001432 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001433 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 +00001434 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001435 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001436 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 -05001437 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001438 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001439 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001440
1441 return Status::OK;
1442}
1443
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001444Status 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 +00001445 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1446 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1447 bcmolt_bin_str buf = {};
1448 bcmolt_gem_port_id gem_port_id_array[1];
1449 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001450
Craig Lutgen967a1d02018-11-27 10:41:51 -06001451 if (port_no > 0) {
1452 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001453 if (gemport_id == 0) {
1454 bcmos_fastlock_lock(&data_lock);
1455 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1456 // Pick any flow that is mapped with the same port_no.
1457 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1458 if (it != port_to_flows.end() && !it->second.empty()) {
1459 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1460 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1461 if (fit != flowid_to_gemport.end()) {
1462 found = true;
1463 gemport_id = fit->second;
1464 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001465 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001466 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001467
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001468 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001469 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 -08001470 onu_id, port_no, intf_id);
1471 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1472 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001473 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 -08001474 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001475 }
1476
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001477 gem_port_id_array[0] = gemport_id;
1478 gem_port_list.len = 1;
1479 gem_port_list.arr = gem_port_id_array;
1480 buf.len = pkt.size();
1481 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1482 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1483
1484 /* init the API struct */
1485 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1486 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1487 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1488 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1489 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1490
1491 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1492 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1493
1494 /* call API */
1495 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001496 }
1497 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001498 //TODO: Port No is 0, it is coming sender requirement.
1499 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1500 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001501 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001502 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001503
1504 return Status::OK;
1505}
1506
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001507Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001508 bcmolt_flow_key key = {}; /* declare key */
1509 bcmolt_bin_str buffer = {};
1510 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001511
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001512 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
Girish Gowdra252f4972020-09-07 21:24:01 -07001513 bcmolt_flow_id flow_id = INVALID_FLOW_ID;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001514
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001515 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1516 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1517 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1518 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1519 key.flow_id = flow_id;
1520 else {
Jason Huang09b73ea2020-01-08 17:52:05 +08001521 if (flow_id_counters) {
1522 std::map<flow_pair, int>::iterator it;
1523 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1524 int flow_index = it->first.first;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001525 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1526 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1527 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1528 key.flow_id = flow_index;
1529 break;
1530 }
1531 }
1532 }
1533 else {
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001534 OPENOLT_LOG(ERROR, openolt_log_id, "no flow id found for uplink packetout\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001535 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1536 }
1537 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001538
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001539 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001540
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001541 /* Initialize the API struct. */
1542 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001543
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001544 buffer.len = pkt.size();
1545 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1546 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1547 if (buffer.arr == NULL) {
1548 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1549 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1550 }
1551 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1552
1553 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1554 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001555 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 -05001556 return bcm_to_grpc_err(BCM_ERR_SYSCALL_ERR, "Error sending packets via nni port");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001557 } else {
1558 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1559 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001560
1561 return Status::OK;
1562}
Girish Gowdra252f4972020-09-07 21:24:01 -07001563
Burak Gurdaga0523592021-02-24 15:17:47 +00001564bool get_aes_flag_for_gem_port(const google::protobuf::Map<unsigned int, bool> &gemport_to_aes, uint32_t gemport_id) {
1565 bool aes_flag = false;
1566 for (google::protobuf::Map<unsigned int, bool>::const_iterator it=gemport_to_aes.begin(); it!=gemport_to_aes.end(); it++) {
1567 if (it->first == gemport_id) {
1568 aes_flag = it->second;
1569 break;
1570 }
1571 }
1572 return aes_flag;
1573}
1574
Girish Gowdra252f4972020-09-07 21:24:01 -07001575Status FlowAddWrapper_(const ::openolt::Flow* request) {
1576
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001577 Status st = Status::OK;
Girish Gowdra252f4972020-09-07 21:24:01 -07001578 int32_t access_intf_id = request->access_intf_id();
1579 int32_t onu_id = request->onu_id();
1580 int32_t uni_id = request->uni_id();
1581 uint32_t port_no = request->port_no();
1582 uint64_t voltha_flow_id = request->flow_id();
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001583 uint64_t symmetric_voltha_flow_id = 0;
Girish Gowdra252f4972020-09-07 21:24:01 -07001584 const std::string flow_type = request->flow_type();
1585 int32_t alloc_id = request->alloc_id();
1586 int32_t network_intf_id = request->network_intf_id();
1587 int32_t gemport_id = request->gemport_id();
1588 const ::openolt::Classifier& classifier = request->classifier();
1589 const ::openolt::Action& action = request->action();
1590 int32_t priority = request->priority();
1591 uint64_t cookie = request->cookie();
1592 int32_t group_id = request->group_id();
1593 uint32_t tech_profile_id = request->tech_profile_id();
1594 bool replicate_flow = request->replicate_flow();
1595 const google::protobuf::Map<unsigned int, unsigned int> &pbit_to_gemport = request->pbit_to_gemport();
Burak Gurdaga0523592021-02-24 15:17:47 +00001596 const google::protobuf::Map<unsigned int, bool> &gemport_to_aes = request->gemport_to_aes();
Girish Gowdra252f4972020-09-07 21:24:01 -07001597 uint16_t flow_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001598 bool enable_encryption;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001599 // When following conditions are ALL met, it qualifies as datapath flow.
1600 // 1. valid access_intf_id, onu_id, uni_id
1601 // 2. Valid tech_profile_id
1602 // 3. flow_type that is not MULTICAST
1603 // 4. Not a trap-to-host flow.
1604 bool datapathFlow = access_intf_id >= 0 && onu_id >= 0 && uni_id >= 0 && tech_profile_id > 0
1605 && flow_type != multicast && !action.cmd().trap_to_host();
1606
1607 if (datapathFlow) {
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08001608 const std::string inverse_flow_type = flow_type == upstream? downstream : upstream;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001609 symmetric_datapath_flow_id_map_key key(access_intf_id, onu_id, uni_id, tech_profile_id, inverse_flow_type);
1610 // Find the onu-uni mapping for the pon-gem key
1611 bcmos_fastlock_lock(&symmetric_datapath_flow_id_lock);
1612 auto it = symmetric_datapath_flow_id_map.find(key);
1613 bcmos_fastlock_unlock(&symmetric_datapath_flow_id_lock, 0);
1614 if (it != symmetric_datapath_flow_id_map.end()) {
1615 symmetric_voltha_flow_id = it->second;
1616 }
1617 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001618
1619 // The intf_id variable defaults to access(PON) interface ID.
1620 // For trap-from-nni flow where access interface ID is not valid , change it to NNI interface ID
1621 // This intf_id identifies the pool from which we get the flow_id
1622 uint32_t intf_id = access_intf_id;
1623 if (onu_id < 1) {
1624 onu_id = 1;
1625 }
1626 if (access_intf_id < 0) {
1627 intf_id = network_intf_id;
1628 }
1629
1630 OPENOLT_LOG(INFO, openolt_log_id, "received flow add. voltha_flow_id=%lu, symmetric_voltha_flow_id=%lu, replication=%d\n", voltha_flow_id, symmetric_voltha_flow_id, replicate_flow)
1631 // This is the case of voltha_flow_id (not symmetric_voltha_flow_id)
1632 if (is_voltha_flow_installed(voltha_flow_id)) {
1633 OPENOLT_LOG(INFO, openolt_log_id, "voltha_flow_id=%lu, already installed\n", voltha_flow_id);
1634 return ::Status(grpc::StatusCode::ALREADY_EXISTS, "voltha-flow-already-installed");
1635 }
1636
Girish Gowdra252f4972020-09-07 21:24:01 -07001637 // This is the case of symmetric_voltha_flow_id
1638 // If symmetric_voltha_flow_id is available and valid in the Flow message,
1639 // check if it is installed, and use the corresponding device_flow_id
1640 if (symmetric_voltha_flow_id > 0 && is_voltha_flow_installed(symmetric_voltha_flow_id)) { // symmetric flow found
1641 OPENOLT_LOG(INFO, openolt_log_id, "symmetric flow and the symmetric flow is installed\n");
1642 const device_flow_params *dev_fl_symm_params;
1643 dev_fl_symm_params = get_device_flow_params(symmetric_voltha_flow_id);
1644 if (dev_fl_symm_params == NULL) {
1645 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)
1646 return ::Status(grpc::StatusCode::INTERNAL, "symmetric-flow-details-not-found");
1647 }
1648
1649 if (!replicate_flow) { // No flow replication
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001650 flow_id = dev_fl_symm_params[0].flow_id;
1651 gemport_id = dev_fl_symm_params[0].gemport_id; // overwrite the gemport with symmetric flow gemport
1652 // Should be same as what is coming in this request.
1653 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
1654 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1655 cl.set_o_pbits(dev_fl_symm_params[0].pbit);
1656 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1657 flow_type, alloc_id, network_intf_id, gemport_id, cl,
1658 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
1659 if (st.error_code() != grpc::StatusCode::OK && st.error_code() != grpc::StatusCode::ALREADY_EXISTS) {
1660 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 -07001661 free_flow_id(flow_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001662 return st;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001663 }
1664
1665 device_flow dev_fl;
1666 dev_fl.is_flow_replicated = false;
1667 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1668 dev_fl.voltha_flow_id = voltha_flow_id;
Girish Gowdra72bb4652022-01-18 17:04:30 -08001669 dev_fl.flow_type = flow_type;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001670 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params));
1671 // update voltha flow to cache
1672 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
Girish Gowdra252f4972020-09-07 21:24:01 -07001673 } else { // Flow to be replicated
1674 OPENOLT_LOG(INFO, openolt_log_id,"symmetric flow and replication is needed\n");
Girish Gowdra52997cc2022-06-02 20:58:50 -07001675 if (pbit_to_gemport.size() > NUMBER_OF_PBITS) {
1676 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pbit-to-gemport map size=%lu", pbit_to_gemport.size())
1677 return ::Status(grpc::StatusCode::OUT_OF_RANGE, "pbit-to-gemport-map-len-invalid-for-flow-replication");
1678 }
1679 for (uint8_t i=0; i<pbit_to_gemport.size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07001680 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1681 flow_id = dev_fl_symm_params[i].flow_id;
1682 gemport_id = dev_fl_symm_params[i].gemport_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001683 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001684 cl.set_o_pbits(dev_fl_symm_params[i].pbit);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001685 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdrade65ab42020-12-17 23:08:43 -08001686 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001687 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001688 if (st.error_code() != grpc::StatusCode::OK && st.error_code() != grpc::StatusCode::ALREADY_EXISTS) {
1689 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);
1690 // On failure remove any successfully replicated flows installed so far for the voltha_flow_id
1691 if (i > 0) {
1692 for (int8_t j = i-1; j >= 0; j--) {
1693 flow_id = dev_fl_symm_params[j].flow_id;
1694 FlowRemove_(flow_id, flow_type);
1695 }
1696 }
Girish Gowdra72cbee92021-11-05 15:16:18 -07001697 // Note: We should not free the flow_ids here because the symmetric flow is already using that flow id.
1698 // 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 -07001699 return st;
1700 }
1701 }
1702 device_flow dev_fl;
1703 dev_fl.is_flow_replicated = true;
1704 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1705 dev_fl.voltha_flow_id = voltha_flow_id;
Girish Gowdra52997cc2022-06-02 20:58:50 -07001706 dev_fl.total_replicated_flows = pbit_to_gemport.size();
Girish Gowdra72bb4652022-01-18 17:04:30 -08001707 dev_fl.flow_type = flow_type;
Girish Gowdra52997cc2022-06-02 20:58:50 -07001708 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params)*dev_fl.total_replicated_flows);
Girish Gowdra252f4972020-09-07 21:24:01 -07001709 // update voltha flow to cache
1710 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1711 }
1712 } else { // No symmetric flow found
1713 if (!replicate_flow) { // No flow replication
1714 OPENOLT_LOG(INFO, openolt_log_id, "not a symmetric flow and replication is not needed\n");
1715 flow_id = get_flow_id();
1716 if (flow_id == INVALID_FLOW_ID) {
1717 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocated flow id for voltha-flow-id=%lu\n", voltha_flow_id);
1718 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1719 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001720 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001721 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001722 flow_type, alloc_id, network_intf_id, gemport_id, classifier,
Burak Gurdaga0523592021-02-24 15:17:47 +00001723 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001724 if (st.error_code() == grpc::StatusCode::OK) {
1725 device_flow dev_fl;
1726 dev_fl.is_flow_replicated = false;
1727 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // Invalid
1728 dev_fl.voltha_flow_id = voltha_flow_id;
Girish Gowdra72bb4652022-01-18 17:04:30 -08001729 dev_fl.flow_type = flow_type;
Girish Gowdra252f4972020-09-07 21:24:01 -07001730 dev_fl.params[0].flow_id = flow_id;
1731 dev_fl.params[0].gemport_id = gemport_id;
1732 dev_fl.params[0].pbit = classifier.o_pbits();
1733 // update voltha flow to cache
1734 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1735 } else {
1736 // Free the flow id on failure
1737 free_flow_id(flow_id);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001738 return st;
Girish Gowdra252f4972020-09-07 21:24:01 -07001739 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001740 } else { // Flow to be replicated
1741 OPENOLT_LOG(INFO, openolt_log_id,"not a symmetric flow and replication is needed\n");
Girish Gowdra52997cc2022-06-02 20:58:50 -07001742 if (pbit_to_gemport.size() > NUMBER_OF_PBITS) {
Girish Gowdra252f4972020-09-07 21:24:01 -07001743 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pbit-to-gemport map size=%lu", pbit_to_gemport.size())
1744 return ::Status(grpc::StatusCode::OUT_OF_RANGE, "pbit-to-gemport-map-len-invalid-for-flow-replication");
1745 }
Girish Gowdra52997cc2022-06-02 20:58:50 -07001746 uint16_t flow_ids[MAX_NUMBER_OF_REPLICATED_FLOWS];
Girish Gowdra252f4972020-09-07 21:24:01 -07001747 device_flow dev_fl;
Girish Gowdra52997cc2022-06-02 20:58:50 -07001748 if (get_flow_ids(pbit_to_gemport.size(), flow_ids)) {
Girish Gowdra252f4972020-09-07 21:24:01 -07001749 uint8_t cnt = 0;
1750 dev_fl.is_flow_replicated = true;
1751 dev_fl.voltha_flow_id = voltha_flow_id;
1752 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // invalid
Girish Gowdra52997cc2022-06-02 20:58:50 -07001753 dev_fl.total_replicated_flows = pbit_to_gemport.size();
Girish Gowdra72bb4652022-01-18 17:04:30 -08001754 dev_fl.flow_type = flow_type;
Girish Gowdra252f4972020-09-07 21:24:01 -07001755 for (google::protobuf::Map<unsigned int, unsigned int>::const_iterator it=pbit_to_gemport.begin(); it!=pbit_to_gemport.end(); it++) {
1756 dev_fl.params[cnt].flow_id = flow_ids[cnt];
1757 dev_fl.params[cnt].pbit = it->first;
1758 dev_fl.params[cnt].gemport_id = it->second;
1759
1760 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1761 flow_id = dev_fl.params[cnt].flow_id;
1762 gemport_id = dev_fl.params[cnt].gemport_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001763 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001764 cl.set_o_pbits(dev_fl.params[cnt].pbit);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001765 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001766 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001767 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001768 if (st.error_code() != grpc::StatusCode::OK) {
1769 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);
1770 // Remove any successfully replicated flows installed so far for the voltha_flow_id
1771 if (cnt > 0) {
1772 for (int8_t j = cnt-1; j >= 0; j--) {
1773 flow_id = dev_fl.params[j].flow_id;
1774 FlowRemove_(flow_id, flow_type);
1775 }
1776 }
1777 // Free up all the flow IDs on failure
Girish Gowdra52997cc2022-06-02 20:58:50 -07001778 free_flow_ids(pbit_to_gemport.size(), flow_ids);
Girish Gowdra252f4972020-09-07 21:24:01 -07001779 return st;
1780 }
1781 cnt++;
1782 }
1783 // On successful flow replication update voltha-flow-id to device-flow map to cache
1784 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1785 } else {
1786 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocate flow ids for replication voltha-flow-id=%lu\n", voltha_flow_id);
1787 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1788 }
1789 }
1790 }
1791
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001792 if (datapathFlow) {
1793 // Create the pon-gem to onu-uni mapping
1794 symmetric_datapath_flow_id_map_key key(access_intf_id, onu_id, uni_id, tech_profile_id, flow_type);
1795 bcmos_fastlock_lock(&symmetric_datapath_flow_id_lock);
1796 symmetric_datapath_flow_id_map[key] = voltha_flow_id;
1797 bcmos_fastlock_unlock(&symmetric_datapath_flow_id_lock, 0);
1798 }
1799
1800 return st;
Girish Gowdra252f4972020-09-07 21:24:01 -07001801}
1802
1803
Craig Lutgen967a1d02018-11-27 10:41:51 -06001804Status 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 +00001805 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001806 int32_t alloc_id, int32_t network_intf_id,
1807 int32_t gemport_id, const ::openolt::Classifier& classifier,
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001808 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie,
Burak Gurdaga0523592021-02-24 15:17:47 +00001809 int32_t group_id, uint32_t tech_profile_id, bool aes_enabled) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001810 bcmolt_flow_cfg cfg;
1811 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001812 int32_t o_vid = -1;
1813 bool single_tag = false;
1814 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001815 bcmolt_classifier c_val = { };
1816 bcmolt_action a_val = { };
1817 bcmolt_tm_queue_ref tm_val = { };
1818 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05001819 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001820
Jason Huang09b73ea2020-01-08 17:52:05 +08001821 OPENOLT_LOG(INFO, openolt_log_id, "flow add received for flow_id=%u, flow_type=%s\n", flow_id, flow_type.c_str());
1822
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001823 key.flow_id = flow_id;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08001824 if (flow_type == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001825 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08001826 } else if (flow_type == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001827 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08001828 } else if (flow_type == multicast) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001829 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001830 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001831 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001832 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001833 }
1834
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001835 BCMOLT_CFG_INIT(&cfg, flow, key);
1836 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001837
Jason Huang09b73ea2020-01-08 17:52:05 +08001838 if (action.cmd().trap_to_host()) {
Girish Gowdra1935e6a2020-10-31 21:48:22 -07001839 Status resp = handle_acl_rule_install(onu_id, flow_id, gemport_id, flow_type, access_intf_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001840 network_intf_id, classifier);
Jason Huang09b73ea2020-01-08 17:52:05 +08001841 return resp;
1842 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001843
1844 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1845
1846 if (access_intf_id >= 0 && network_intf_id >= 0) {
1847 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1848 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1849 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08001850 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1851 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001852 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1853 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1854 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1855 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1856 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001857 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001858 } else {
1859 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
1860 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001861 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001862
Burak Gurdaga0523592021-02-24 15:17:47 +00001863 if (onu_id >= ONU_ID_START) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001864 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
1865 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001866 if (gemport_id >= GEM_PORT_ID_START) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001867 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
1868 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001869 if (gemport_id >= GEM_PORT_ID_START && port_no != 0) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001870 bcmos_fastlock_lock(&data_lock);
1871 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
1872 port_to_flows[port_no].insert(key.flow_id);
1873 flowid_to_gemport[key.flow_id] = gemport_id;
1874 }
1875 else
1876 {
1877 flowid_to_port[key.flow_id] = port_no;
1878 }
1879 bcmos_fastlock_unlock(&data_lock, 0);
1880 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001881
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001882 if (priority_value >= 0) {
1883 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
1884 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301885
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001886 } else { // MULTICAST FLOW
1887 if (group_id >= 0) {
1888 BCMOLT_MSG_FIELD_SET(&cfg, group_id, group_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001889 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001890 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1891 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001892 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001893
1894 {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001895 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001896 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001897 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
1898 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001899 }
1900
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001901 if (classifier.dst_mac().size() > 0) {
1902 bcmos_mac_address d_mac = {};
1903 bcmos_mac_address_init(&d_mac);
1904 memcpy(d_mac.u8, classifier.dst_mac().data(), sizeof(d_mac.u8));
1905 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_mac %02x:%02x:%02x:%02x:%02x:%02x\n", d_mac.u8[0],
1906 d_mac.u8[1], d_mac.u8[2], d_mac.u8[3], d_mac.u8[4], d_mac.u8[5]);
1907 BCMOLT_FIELD_SET(&c_val, classifier, dst_mac, d_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001908 }
1909
Girish Gowdraf83e17a2022-02-16 16:27:00 -08001910 if (classifier.src_mac().size() > 0) {
1911 bcmos_mac_address s_mac = {};
1912 bcmos_mac_address_init(&s_mac);
1913 memcpy(s_mac.u8, classifier.src_mac().data(), sizeof(s_mac.u8));
1914 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_mac %02x:%02x:%02x:%02x:%02x:%02x\n", s_mac.u8[0],
1915 s_mac.u8[1], s_mac.u8[2], s_mac.u8[3], s_mac.u8[4], s_mac.u8[5]);
1916 BCMOLT_FIELD_SET(&c_val, classifier, src_mac, s_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001917 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001918
1919 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001920 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
1921 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001922 }
1923
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001924 if (classifier.dst_ip()) {
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08001925 bcmos_ipv4_address d_ip = {};
1926 bcmos_ipv4_address_init(&d_ip);
1927 d_ip.u32 = classifier.dst_ip();
1928 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_ip %04x\n", d_ip.u32);
1929 BCMOLT_FIELD_SET(&c_val, classifier, dst_ip, d_ip);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001930 }
1931
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08001932 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001933 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001934 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001935 }
1936 */
1937
1938 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001939 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
1940 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001941 }
1942
1943 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001944 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
1945 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001946 }
1947
1948 if (!classifier.pkt_tag_type().empty()) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001949 if (classifier.o_vid()) {
1950 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
1951 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
1952 }
1953
1954 if (classifier.i_vid()) {
1955 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
1956 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
1957 }
1958
1959 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
1960 if (classifier.pkt_tag_type().compare("untagged") == 0) {
1961 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
1962 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
1963 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
1964 single_tag = true;
1965
1966 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301967 // OpenOlt adapter will send 0xFF in case of no pbit classification
1968 // If it is any other value (0 to 7), it is for outer pbit classification.
1969 // OpenFlow protocol does not provide inner pbit classification (in case of double tagged packets),
1970 // and VOLTHA has not used any workaround to solve this problem (for ex: use metadata field).
1971 // Also there exists no use case for i-pbit classification, so we can safely ignore this for now.
1972 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001973 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301974 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001975 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
1976 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001977
Jason Huang09b73ea2020-01-08 17:52:05 +08001978 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301979 // Same comments as in case of "single_tag" packets.
1980 // 0xFF means no pbit classification, otherwise a valid PCP (0 to 7).
1981 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001982 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301983 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001984 }
1985 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001986 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001987 }
1988
Jason Huang09b73ea2020-01-08 17:52:05 +08001989 const ::openolt::ActionCmd& cmd = action.cmd();
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001990
Jason Huang09b73ea2020-01-08 17:52:05 +08001991 if (cmd.add_outer_tag()) {
1992 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
1993 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001994 }
1995
Jason Huang09b73ea2020-01-08 17:52:05 +08001996 if (cmd.remove_outer_tag()) {
1997 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
1998 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
1999 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05302000
Girish Gowdraf83e17a2022-02-16 16:27:00 -08002001 if (cmd.translate_outer_tag()) {
2002 OPENOLT_LOG(DEBUG, openolt_log_id, "action translate o_tag\n");
2003 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_XLATE_OUTER_TAG);
2004 }
2005
Jason Huang09b73ea2020-01-08 17:52:05 +08002006 if (action.o_vid()) {
2007 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
2008 o_vid = action.o_vid();
2009 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
2010 }
2011
2012 if (action.o_pbits()) {
2013 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
2014 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
2015 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05302016
Jason Huang09b73ea2020-01-08 17:52:05 +08002017 if (action.i_vid()) {
2018 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
2019 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
2020 }
2021
2022 if (action.i_pbits()) {
2023 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
2024 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
2025 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05302026
Jason Huang09b73ea2020-01-08 17:52:05 +08002027 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
2028
Burak Gurdaga0523592021-02-24 15:17:47 +00002029 if ((access_intf_id >= 0) && (onu_id >= ONU_ID_START)) {
Jason Huang09b73ea2020-01-08 17:52:05 +08002030 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
2031 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002032 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 +00002033
Jason Huang09b73ea2020-01-08 17:52:05 +08002034 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2035 // Queue 0 on DS subscriber scheduler
2036 tm_val.queue_id = 0;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002037
Jason Huang09b73ea2020-01-08 17:52:05 +08002038 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2039 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2040 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002041
Jason Huang09b73ea2020-01-08 17:52:05 +08002042 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2043 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2044 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002045
Jason Huang09b73ea2020-01-08 17:52:05 +08002046 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2047 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
2048 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 +00002049
Jason Huang09b73ea2020-01-08 17:52:05 +08002050 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2051 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2052 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2053 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 +00002054
Jason Huang09b73ea2020-01-08 17:52:05 +08002055 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2056 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2057 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2058 }
2059 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
2060 // NNI Scheduler ID
2061 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2062 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2063 // Queue 0 on NNI scheduler
2064 tm_val.queue_id = 0;
2065 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2066 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2067 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002068
Jason Huang09b73ea2020-01-08 17:52:05 +08002069 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 +00002070 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2071 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2072
Jason Huang09b73ea2020-01-08 17:52:05 +08002073 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2074 /* Fetch TM QMP ID mapped to US NNI scheduler */
2075 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2076 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2077 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2078 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2079 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 +00002080
Jason Huang09b73ea2020-01-08 17:52:05 +08002081 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002082 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2083 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002084 }
Shad Ansari39739bc2018-09-13 21:38:37 +00002085 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302086 } else {
2087 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2088 tm_val.queue_id = 0;
2089
2090 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2091 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2092 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2093
2094 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2095 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
2096 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00002097 }
2098
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002099 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002100
Girish Gowdra252f4972020-09-07 21:24:01 -07002101#ifndef SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002102 // BAL 3.1 supports statistics only for unicast flows.
2103 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
2104 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
2105 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002106#endif // SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002107
Girish Gowdra252f4972020-09-07 21:24:01 -07002108#ifndef SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002109#ifdef FLOW_CHECKER
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002110 //Flow Checker, To avoid duplicate flow.
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002111 if (flow_id_counters != 0) {
2112 bool b_duplicate_flow = false;
Jason Huang09b73ea2020-01-08 17:52:05 +08002113 std::map<flow_pair, int>::iterator it;
2114
2115 for(it = flow_map.begin(); it != flow_map.end(); it++) {
2116 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(it->first.first, it->first.second, ONU_ID)) && \
2117 (key.flow_type == it->first.second) && \
2118 (cfg.data.svc_port_id == get_flow_status(it->first.first, it->first.second, SVC_PORT_ID)) && \
2119 (cfg.data.priority == get_flow_status(it->first.first, it->first.second, PRIORITY)) && \
2120 (cfg.data.cookie == get_flow_status(it->first.first, it->first.second, COOKIE)) && \
2121 (cfg.data.ingress_intf.intf_type == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_TYPE)) && \
2122 (cfg.data.ingress_intf.intf_id == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_ID)) && \
2123 (cfg.data.egress_intf.intf_type == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_TYPE)) && \
2124 (cfg.data.egress_intf.intf_id == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_ID)) && \
2125 (c_val.o_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_VID)) && \
2126 (c_val.o_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_PBITS)) && \
2127 (c_val.i_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_VID)) && \
2128 (c_val.i_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_PBITS)) && \
2129 (c_val.ether_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_ETHER_TYPE)) && \
2130 (c_val.ip_proto == get_flow_status(it->first.first, it->first.second, CLASSIFIER_IP_PROTO)) && \
2131 (c_val.src_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_SRC_PORT)) && \
2132 (c_val.dst_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_DST_PORT)) && \
2133 (c_val.pkt_tag_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_PKT_TAG_TYPE)) && \
2134 (cfg.data.egress_qos.type == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TYPE)) && \
2135 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_QUEUE_ID)) && \
2136 (cfg.data.egress_qos.tm_sched.id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TM_SCHED_ID)) && \
2137 (a_val.cmds_bitmask == get_flow_status(it->first.first, it->first.second, ACTION_CMDS_BITMASK)) && \
2138 (a_val.o_vid == get_flow_status(it->first.first, it->first.second, ACTION_O_VID)) && \
2139 (a_val.i_vid == get_flow_status(it->first.first, it->first.second, ACTION_I_VID)) && \
2140 (a_val.o_pbits == get_flow_status(it->first.first, it->first.second, ACTION_O_PBITS)) && \
2141 (a_val.i_pbits == get_flow_status(it->first.first, it->first.second, ACTION_I_PBITS)) && \
2142 (cfg.data.state == get_flow_status(it->first.first, it->first.second, STATE)) && \
2143 (cfg.data.group_id == get_flow_status(it->first.first, it->first.second, GROUP_ID));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002144#ifdef SHOW_FLOW_PARAM
2145 // Flow Parameter
2146 FLOW_PARAM_LOG();
2147#endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002148 if (b_duplicate_flow) {
2149 FLOW_LOG(WARNING, "Flow duplicate", 0);
2150 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
2151 }
2152 }
2153 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002154#endif // FLOW_CHECKER
2155#endif // SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002156
2157 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2158 if (err) {
2159 FLOW_LOG(ERROR, "Flow add failed", err);
2160 return bcm_to_grpc_err(err, "flow add failed");
2161 } else {
2162 FLOW_LOG(INFO, "Flow add ok", err);
2163 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002164 flow_map[std::pair<int, int>(key.flow_id,key.flow_type)] = flow_map.size();
2165 flow_id_counters = flow_map.size();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002166 bcmos_fastlock_unlock(&data_lock, 0);
Girish Gowdra252f4972020-09-07 21:24:01 -07002167
2168 }
Burak Gurdaga0523592021-02-24 15:17:47 +00002169
2170 /*
2171 Enable AES encryption on GEM ports if they are used in downstream unicast flows.
2172 Rationale: We can't do upstream encryption in GPON. This change addresses the common denominator (and also minimum viable)
2173 use case for both technologies which is downstream unicast GEM port encryption. Since the downstream traffic is inherently
2174 broadcast to all the ONUs behind a PON port, encrypting the individual subscriber traffic in this direction is important
2175 and considered good enough in terms of security (See Section 12.1 of G.984.3). For upstream unicast and downstream multicast
2176 GEM encryption, we need to make additional changes specific to XGSPON. This will be done as a future work.
2177 */
2178 if (aes_enabled && (access_intf_id >= 0) && (gemport_id >= GEM_PORT_ID_START) && (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM)) {
2179 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 +05302180 enable_encryption_for_gem_port(access_intf_id, gemport_id, board_technology);
Burak Gurdaga0523592021-02-24 15:17:47 +00002181 } else {
2182 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);
2183 }
2184
Girish Gowdra252f4972020-09-07 21:24:01 -07002185 return Status::OK;
2186}
2187
2188Status FlowRemoveWrapper_(const ::openolt::Flow* request) {
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002189 int32_t access_intf_id = request->access_intf_id();
2190 int32_t onu_id = request->onu_id();
2191 int32_t uni_id = request->uni_id();
2192 uint32_t tech_profile_id = request->tech_profile_id();
Girish Gowdra252f4972020-09-07 21:24:01 -07002193 uint64_t voltha_flow_id = request->flow_id();
2194 Status st;
2195
2196 // If Voltha flow is not installed, return fail
2197 if (! is_voltha_flow_installed(voltha_flow_id)) {
2198 OPENOLT_LOG(ERROR, openolt_log_id, "voltha_flow_id=%lu not found\n", voltha_flow_id);
2199 return ::Status(grpc::StatusCode::NOT_FOUND, "voltha-flow-not-found");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002200 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04002201
Girish Gowdra252f4972020-09-07 21:24:01 -07002202 const device_flow *dev_fl = get_device_flow(voltha_flow_id);
2203 if (dev_fl == NULL) {
2204 OPENOLT_LOG(ERROR, openolt_log_id, "device flow for voltha_flow_id=%lu in the cache is NULL\n", voltha_flow_id);
2205 return ::Status(grpc::StatusCode::INTERNAL, "device-flow-null-in-cache");
2206 }
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002207 std::string flow_type = dev_fl->flow_type;
Girish Gowdra252f4972020-09-07 21:24:01 -07002208 if (dev_fl->is_flow_replicated) {
2209 // Note: Here we are ignoring FlowRemove failures
Girish Gowdra52997cc2022-06-02 20:58:50 -07002210 for (int i=0; i<dev_fl->total_replicated_flows; i++) {
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002211 st = FlowRemove_(dev_fl->params[i].flow_id, flow_type);
Girish Gowdra252f4972020-09-07 21:24:01 -07002212 if (st.error_code() == grpc::StatusCode::OK) {
2213 free_flow_id(dev_fl->params[i].flow_id);
2214 }
2215 }
2216 } else {
2217 // Note: Here we are ignoring FlowRemove failures
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002218 st = FlowRemove_(dev_fl->params[0].flow_id, flow_type);
Girish Gowdra252f4972020-09-07 21:24:01 -07002219 if (st.error_code() == grpc::StatusCode::OK) {
2220 free_flow_id(dev_fl->params[0].flow_id);
2221 }
2222 }
2223 // remove the flow from cache on voltha flow removal
2224 remove_voltha_flow_from_cache(voltha_flow_id);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002225
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002226 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 -07002227 // Remove onu-uni mapping for the pon-gem key
2228 bcmos_fastlock_lock(&symmetric_datapath_flow_id_lock);
2229 symmetric_datapath_flow_id_map.erase(key);
2230 bcmos_fastlock_unlock(&symmetric_datapath_flow_id_lock, 0);
2231
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002232 return Status::OK;
2233}
2234
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002235Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
2236
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002237 bcmolt_flow_cfg cfg;
2238 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002239
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002240 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002241 key.flow_id = flow_id;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002242 if (flow_type == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002243 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002244 } else if (flow_type == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002245 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002246 } else if(flow_type == multicast) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002247 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002248 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002249 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002250 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
2251 }
2252
Jason Huang09b73ea2020-01-08 17:52:05 +08002253 OPENOLT_LOG(INFO, openolt_log_id, "flow remove received for flow_id=%u, flow_type=%s\n",
2254 flow_id, flow_type.c_str());
2255
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002256 bcmos_fastlock_lock(&acl_packet_trap_handler_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002257 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
2258 int32_t gemport_id = -1;
2259 int32_t intf_id = -1;
2260 int16_t acl_id = -1;
2261 if (flow_to_acl_map.count(fl_id_fl_dir) > 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002262
2263 acl_id_intf_id ac_id_if_id = flow_to_acl_map[fl_id_fl_dir];
2264 acl_id = std::get<0>(ac_id_if_id);
2265 intf_id = std::get<1>(ac_id_if_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002266 // cleanup acl only if it is a valid acl. If not valid acl, it may be datapath flow.
2267 if (acl_id >= 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002268 Status resp = handle_acl_rule_cleanup(acl_id, intf_id, flow_type);
Jason Huang09b73ea2020-01-08 17:52:05 +08002269 if (resp.ok()) {
2270 OPENOLT_LOG(INFO, openolt_log_id, "acl removed ok for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2271 flow_to_acl_map.erase(fl_id_fl_dir);
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002272
2273 // 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
2274 if (trap_to_host_pkt_info_with_vlan_for_flow_id.count(flow_id) > 0) {
2275 trap_to_host_pkt_info_with_vlan pkt_info_with_vlan = trap_to_host_pkt_info_with_vlan_for_flow_id[flow_id];
2276 // Formulate the trap_to_host_pkt_info tuple key
2277 trap_to_host_pkt_info pkt_info(std::get<0>(pkt_info_with_vlan),
2278 std::get<1>(pkt_info_with_vlan),
2279 std::get<2>(pkt_info_with_vlan),
2280 std::get<3>(pkt_info_with_vlan));
2281 // Extract the value corresponding to trap_to_host_pkt_info key from trap_to_host_vlan_ids_for_trap_to_host_pkt_info
2282 // The value is a list of vlan_ids for the given trap_to_host_pkt_info key
2283 // Remove the vlan_id from the list that corresponded to the flow being removed.
2284 if (trap_to_host_vlan_ids_for_trap_to_host_pkt_info.count(pkt_info) > 0) {
2285 trap_to_host_vlan_ids_for_trap_to_host_pkt_info[pkt_info].remove(std::get<4>(pkt_info_with_vlan));
2286 } else {
2287 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",
2288 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));
2289 }
2290
2291 } else {
2292 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);
2293 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002294 } else {
2295 OPENOLT_LOG(ERROR, openolt_log_id, "acl remove error for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2296 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002297 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002298 return resp;
2299 }
2300 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002301 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002302
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002303 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002304 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002305 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002306 flowid_to_gemport.erase(key.flow_id);
2307 port_to_flows[port_no].erase(key.flow_id);
2308 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
2309 }
2310 else
2311 {
2312 flowid_to_port.erase(key.flow_id);
2313 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002314 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002315
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002316 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002317
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002318 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002319 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07002320 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 -04002321 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
2322 }
2323
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002324 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002325 if (flow_id_counters != 0) {
2326 std::map<flow_pair, int>::iterator it;
2327 for(it = flow_map.begin(); it != flow_map.end(); it++) {
2328 if (it->first.first == flow_id && it->first.second == key.flow_type) {
2329 flow_id_counters -= 1;
2330 flow_map.erase(it);
Shivanagouda Malaginahallie707d612023-08-22 10:40:25 +00002331 break; /* After match found break from the loop, otherwise leads to crash */
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002332 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002333 }
2334 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002335 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
2336
Jason Huang09b73ea2020-01-08 17:52:05 +08002337 flow_to_acl_map.erase(fl_id_fl_dir);
2338
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002339 bcmos_fastlock_unlock(&data_lock, 0);
2340
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002341 return Status::OK;
2342}
2343
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002344bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
2345 bcmos_errno err;
2346 bcmolt_tm_sched_cfg tm_sched_cfg;
2347 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2348 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
2349
Jason Huangbf45ffb2019-10-30 17:29:02 +08002350 //check TM scheduler has configured or not
2351 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2352 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002353 #ifdef TEST_MODE
2354 // It is impossible to mock the setting of tm_sched_cfg.data.state because
2355 // the actual bcmolt_cfg_get passes the address of tm_sched_cfg.hdr and we cannot
2356 // set the tm_sched_cfg.data.state. So a new stub function is created and address
2357 // of tm_sched_cfg is passed. This is one-of case where we need to add test specific
2358 // code in production code.
2359 err = bcmolt_cfg_get__tm_sched_stub(dev_id, &tm_sched_cfg);
2360 #else
Jason Huangbf45ffb2019-10-30 17:29:02 +08002361 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002362 #endif
Jason Huangbf45ffb2019-10-30 17:29:02 +08002363 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07002364 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 +08002365 return err;
2366 }
2367 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
2368 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
2369 return BCM_ERR_OK;
2370 }
2371
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002372 // bcmbal_tm_sched_owner
2373 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2374
2375 /**< The output of the tm_sched object instance */
2376 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
2377
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002378 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002379 // In upstream it is NNI scheduler
2380 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 -08002381 } else if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002382 // In downstream it is PON scheduler
2383 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2384 }
2385
2386 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2387
2388 // bcmbal_tm_sched_type
2389 // set the deafult policy to strict priority
2390 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2391
2392 // num_priorities: Max number of strict priority scheduling elements
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002393 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, NUM_OF_PRIORITIES);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002394
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002395 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2396 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002397 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
2398 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002399 return err;
2400 }
2401
2402 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2403 direction.c_str(), tm_sched_key.id, intf_id);
2404 return BCM_ERR_OK;
2405}
2406
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002407bcmos_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 -07002408 uint32_t alloc_id, ::tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
2409 ::tech_profile::SchedulingPolicy sched_policy, ::tech_profile::TrafficShapingInfo tf_sh_info,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002410 uint32_t tech_profile_id) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002411
2412 bcmos_errno err;
2413
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002414 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002415 bcmolt_tm_sched_cfg tm_sched_cfg;
2416 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002417 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 -04002418
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002419 // bcmbal_tm_sched_owner
2420 // In downstream it is sub_term scheduler
2421 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002422
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002423 /**< The output of the tm_sched object instance */
2424 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002425
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002426 // bcmbal_tm_sched_parent
2427 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2428 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 +00002429 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 +00002430 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 +00002431 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002432 be achieved using the' virtual' type of attachment.
2433 tm_sched_owner.u.sub_term.intf_id = intf_id;
2434 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2435 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002436
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002437 // bcmbal_tm_sched_type
2438 // set the deafult policy to strict priority
2439 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002440
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002441 // num_priorities: Max number of strict priority scheduling elements
2442 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002443
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002444 // bcmbal_tm_shaping
2445 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2446 uint32_t cir = tf_sh_info.cir();
2447 uint32_t pir = tf_sh_info.pir();
2448 uint32_t burst = tf_sh_info.pbs();
2449 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2450 cir, pir, burst);
2451 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2452 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2453 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2454 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2455 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2456 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002457 }
2458
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002459 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002460 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002461 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Girish Gowdra72cbee92021-11-05 15:16:18 -07002462intf_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, \
2463port_no, tm_sched_cfg.hdr.hdr.err_text, err);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002464 return err;
2465 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002466 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2467uni_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 -08002468
2469 } else { //upstream
Arthur Syu094df162022-04-21 17:50:06 +08002470 std::string intf_technology = intf_technologies[intf_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002471 bcmolt_itupon_alloc_cfg cfg;
2472 bcmolt_itupon_alloc_key key = { };
2473 key.pon_ni = intf_id;
2474 key.alloc_id = alloc_id;
Arthur Syu094df162022-04-21 17:50:06 +08002475 int bw_granularity = (intf_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
Burak Gurdag623fada2021-04-20 22:02:36 +00002476 /*
2477 PIR: Maximum Bandwidth
2478 CIR: Assured Bandwidth
2479 GIR: Fixed Bandwidth
2480 */
Burak Gurdag03919c72020-02-04 22:46:57 +00002481 int pir_bw = tf_sh_info.pir()*125; // conversion from kbps to bytes/sec
2482 int cir_bw = tf_sh_info.cir()*125; // conversion from kbps to bytes/sec
Burak Gurdag623fada2021-04-20 22:02:36 +00002483 int gir_bw = tf_sh_info.gir()*125; // conversion from kbps to bytes/sec
2484 int guaranteed_bw = cir_bw+gir_bw;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002485 //offset to match bandwidth granularity
2486 int offset_pir_bw = pir_bw%bw_granularity;
Burak Gurdag623fada2021-04-20 22:02:36 +00002487 int offset_gir_bw = gir_bw%bw_granularity;
2488 int offset_guaranteed_bw = guaranteed_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002489
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002490 pir_bw = pir_bw - offset_pir_bw;
Burak Gurdag623fada2021-04-20 22:02:36 +00002491 gir_bw = gir_bw - offset_gir_bw;
2492 guaranteed_bw = guaranteed_bw - offset_guaranteed_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002493
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002494 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002495
Burak Gurdag623fada2021-04-20 22:02:36 +00002496 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);
2497
2498 if (pir_bw == 0) {
2499 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be at least %d bytes/sec\n",
2500 (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2501 return BCM_ERR_PARM;
2502 } else if (pir_bw < guaranteed_bw) {
2503 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed bandwidth (%d)\n",
2504 pir_bw, guaranteed_bw);
2505 return BCM_ERR_PARM;
2506 }
2507
2508 // Setting additional bw eligibility and validating bw provisionings
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002509 switch (additional_bw) {
Burak Gurdag623fada2021-04-20 22:02:36 +00002510
2511 case tech_profile::AdditionalBW::AdditionalBW_BestEffort: //AdditionalBW_BestEffort - For T-Cont types 4 & 5
2512 if (pir_bw == guaranteed_bw) {
2513 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2514bandwidth for additional bandwidth eligibility of type Best Effort\n");
2515 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002516 }
2517 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2518 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002519
2520 case tech_profile::AdditionalBW::AdditionalBW_NA: //AdditionalBW_NA - For T-Cont types 3 & 5
2521 if (guaranteed_bw == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002522 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2523additional bandwidth eligibility of type Non-Assured (NA)\n");
2524 return BCM_ERR_PARM;
Burak Gurdag623fada2021-04-20 22:02:36 +00002525 } else if (pir_bw == guaranteed_bw) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002526 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
Burak Gurdag623fada2021-04-20 22:02:36 +00002527bandwidth for additional bandwidth eligibility of type Non-Assured\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002528 return BCM_ERR_PARM;
2529 }
2530 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2531 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002532
2533 case tech_profile::AdditionalBW::AdditionalBW_None: //AdditionalBW_None - For T-Cont types 1 & 2
2534 if (guaranteed_bw != pir_bw) {
2535 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be equal to maximum bandwidth \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002536for additional bandwidth eligibility of type None\n");
2537 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002538 }
2539 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2540 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002541
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002542 default:
Burak Gurdag623fada2021-04-20 22:02:36 +00002543 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid additional bandwidth eligibility value (%d) supplied.\n", additional_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002544 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002545 }
Burak Gurdag623fada2021-04-20 22:02:36 +00002546
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002547 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2548 in a fine granularity. */
2549 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
Burak Gurdag623fada2021-04-20 22:02:36 +00002550 /* Since we can assign minimum 64000 bytes/sec for cbr_rt_bw, we prefer assigning
2551 gir_bw to cbr_nrt_bw to allow smaller amounts.
2552 TODO: Specify CBR_RT_BW and CBR_NRT_BW separately from VOLTHA */
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002553 /* Fixed Bandwidth with no critical requirement of shaping */
Burak Gurdag623fada2021-04-20 22:02:36 +00002554 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, gir_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002555 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
Burak Gurdag623fada2021-04-20 22:02:36 +00002556 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, guaranteed_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002557 /* Maximum allocated bandwidth allowed for this alloc ID */
2558 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
Burak Gurdag623fada2021-04-20 22:02:36 +00002559
2560 if (pir_bw == gir_bw) { // T-Cont Type 1 --> set alloc type to NONE
2561 // the condition cir_bw == 0 is implicitly satistied
2562 OPENOLT_LOG(INFO, openolt_log_id, "Setting alloc type to NONE since maximum bandwidth is equal to fixed bandwidth\n");
2563 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NONE);
2564 } else { // For other T-Cont types, set alloc type to NSR. TODO: read the default from a config file.
2565 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
2566 }
2567
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002568 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002569 for skipped allocations during quiet window */
2570 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2571 /**< Allocation Profile index for CBR non-RT Bandwidth */
2572 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2573 /**< Allocation Profile index for CBR RT Bandwidth */
2574 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2575 /**< Alloc ID Weight used in case of Extended DBA mode */
2576 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2577 /**< Alloc ID Priority used in case of Extended DBA mode */
2578 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2579 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002580
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302581 bcmolt_onu_state onu_state;
2582 bool wait_for_alloc_cfg_cmplt = false;
2583 err = get_onu_state((bcmolt_interface)intf_id, (bcmolt_onu_id)onu_id, &onu_state);
2584 if (err) {
2585 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch onu status, intf_id = %d, onu_id = %d, err = %s\n",
2586 intf_id, onu_id, bcmos_strerror(err));
2587 return err;
2588 } else if (onu_state == BCMOLT_ONU_STATE_ACTIVE) {
2589 wait_for_alloc_cfg_cmplt = true;
2590 }
2591
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002592 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002593 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002594 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 -07002595port_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 -08002596 return err;
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302597 } else if (wait_for_alloc_cfg_cmplt) {
2598 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
2599 if (err) {
2600 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 +05302601port_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 +05302602 return err;
Girish Gowdra72cbee92021-11-05 15:16:18 -07002603 }
2604 } else {
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302605 OPENOLT_LOG(INFO, openolt_log_id, "onu not active, not waiting for alloc cfg complete, onu_state = %d, intf = %d, onu=%d\n",
2606 onu_state, intf_id, onu_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302607 }
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302608
Girish Gowdra96461052019-11-22 20:13:59 +05302609 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
2610port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
2611
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002612 }
2613
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002614 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002615}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002616
Girish Gowdra252f4972020-09-07 21:24:01 -07002617Status CreateTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002618 uint32_t intf_id = traffic_scheds->intf_id();
2619 uint32_t onu_id = traffic_scheds->onu_id();
2620 uint32_t uni_id = traffic_scheds->uni_id();
2621 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002622 std::string direction;
2623 unsigned int alloc_id;
Girish Gowdra252f4972020-09-07 21:24:01 -07002624 ::tech_profile::SchedulerConfig sched_config;
2625 ::tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002626 uint32_t priority;
2627 uint32_t weight;
Girish Gowdra252f4972020-09-07 21:24:01 -07002628 ::tech_profile::SchedulingPolicy sched_policy;
2629 ::tech_profile::TrafficShapingInfo traffic_shaping_info;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002630 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002631 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002632
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002633 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002634 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002635
2636 direction = GetDirection(traffic_sched.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002637 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002638 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002639 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002640
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002641 alloc_id = traffic_sched.alloc_id();
2642 sched_config = traffic_sched.scheduler();
2643 additional_bw = sched_config.additional_bw();
2644 priority = sched_config.priority();
2645 weight = sched_config.weight();
2646 sched_policy = sched_config.sched_policy();
2647 traffic_shaping_info = traffic_sched.traffic_shaping_info();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002648 tech_profile_id = traffic_sched.tech_profile_id();
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002649 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002650 sched_policy, traffic_shaping_info, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002651 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002652 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002653 return bcm_to_grpc_err(err, "Failed to create scheduler");
2654 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002655 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002656 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002657}
Jonathan Davis70c21812018-07-19 15:32:10 -04002658
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002659bcmos_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 -04002660
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002661 bcmos_errno err;
Girish Gowdra72cbee92021-11-05 15:16:18 -07002662 bcmolt_onu_state onu_state;
Girish Gowdra96461052019-11-22 20:13:59 +05302663 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002664
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002665 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002666 bcmolt_itupon_alloc_cfg cfg;
2667 bcmolt_itupon_alloc_key key = { };
2668 key.pon_ni = intf_id;
2669 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302670 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002671
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302672 bcmolt_onu_state onu_state;
2673 bool wait_for_alloc_cfg_cmplt = false;
2674 err = get_onu_state((bcmolt_interface)intf_id, (bcmolt_onu_id)onu_id, &onu_state);
2675 if (err) {
2676 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch onu status, intf_id = %d, onu_id = %d, err = %s\n",
2677 intf_id, onu_id, bcmos_strerror(err));
2678 return err;
2679 } else if (onu_state == BCMOLT_ONU_STATE_ACTIVE) {
2680 wait_for_alloc_cfg_cmplt = true;
2681 }
2682
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002683 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002684 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2685 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07002686 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s (%d)\n",
2687 direction.c_str(), intf_id, alloc_id, cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002688 return err;
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302689 } else if (wait_for_alloc_cfg_cmplt) {
2690 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2691 if (err) {
2692 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2693pon_intf %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,intf_id,alloc_id, bcmos_strerror(err));
2694 return err;
2695 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302696 } else {
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302697 OPENOLT_LOG(INFO, openolt_log_id, "onu not active, not waiting for alloc cfg complete, onu_state = %d, intf = %d, onu=%d\n",
2698 onu_state, intf_id, onu_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302699 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002700 } else if (direction == downstream) {
2701 bcmolt_tm_sched_cfg cfg;
2702 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002703
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002704 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2705 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302706 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002707 } else {
2708 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2709 return BCM_ERR_OK;
2710 }
Girish Gowdra96461052019-11-22 20:13:59 +05302711
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002712 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2713 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2714 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002715 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
Girish Gowdra72cbee92021-11-05 15:16:18 -07002716intf_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 +00002717 return err;
2718 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002719 }
2720
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002721 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d, tech_profile_id %d\n",
2722 direction.c_str(), sched_id, intf_id, onu_id, tech_profile_id);
2723 free_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002724 return BCM_ERR_OK;
2725}
2726
Girish Gowdra252f4972020-09-07 21:24:01 -07002727Status RemoveTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002728 uint32_t intf_id = traffic_scheds->intf_id();
2729 uint32_t onu_id = traffic_scheds->onu_id();
2730 uint32_t uni_id = traffic_scheds->uni_id();
2731 std::string direction;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002732 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002733 bcmos_errno err;
2734
2735 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002736 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002737
2738 direction = GetDirection(traffic_sched.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002739 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002740 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002741 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002742
2743 int alloc_id = traffic_sched.alloc_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002744 int tech_profile_id = traffic_sched.tech_profile_id();
2745 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002746 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002747 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002748 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2749 }
2750 }
2751 return Status::OK;
2752}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002753
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002754bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2755 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002756 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002757 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2758 bcmolt_tm_qmp_key tm_qmp_key;
2759 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002760
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002761 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2762 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002763 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed tm queue mapping profile count is 16.\n");
2764 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002765 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002766
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002767 tm_qmp_key.id = tm_qmp_id;
2768 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2769 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2770 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002771
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002772 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2773 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2774 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002775 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2776 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002777
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002778 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002779 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002780 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2781 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002782 return err;
2783 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002784
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002785 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2786 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002787 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002788}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002789
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002790bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2791 bcmos_errno err;
2792 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2793 bcmolt_tm_qmp_key tm_qmp_key;
2794 tm_qmp_key.id = tm_qmp_id;
2795
2796 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2797 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2798 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002799 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2800 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002801 return err;
2802 }
2803
2804 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2805 tm_qmp_key.id);
2806 return BCM_ERR_OK;
2807}
2808
2809bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2810 bcmos_errno err;
2811
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002812 /* Create default queues on the given PON/NNI scheduler */
2813 for (int queue_id = 0; queue_id < NUMBER_OF_DEFAULT_INTERFACE_QUEUES; queue_id++) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002814 bcmolt_tm_queue_cfg tm_queue_cfg;
2815 bcmolt_tm_queue_key tm_queue_key = {};
2816 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2817 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002818 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2819 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2820 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002821
2822 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2823 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2824 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2825
2826 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2827 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002828 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", \
2829 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 +00002830 return err;
2831 }
2832
2833 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2834 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2835 }
2836 return BCM_ERR_OK;
2837}
2838
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002839bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002840 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 +00002841 bcmos_errno err;
2842 bcmolt_tm_queue_cfg cfg;
2843 bcmolt_tm_queue_key key = { };
2844 OPENOLT_LOG(INFO, openolt_log_id, "creating %s queue. access_intf_id = %d, onu_id = %d, uni_id = %d \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002845gemport_id = %d, tech_profile_id = %d\n", direction.c_str(), access_intf_id, onu_id, uni_id, gemport_id, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002846
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002847 key.sched_id = (direction == upstream) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002848 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002849
2850 if (priority > 7) {
2851 return BCM_ERR_RANGE;
2852 }
2853
2854 /* FIXME: The upstream queues have to be created once only.
2855 The upstream queues on the NNI scheduler are shared by all subscribers.
2856 When the first scheduler comes in, the queues get created, and are re-used by all others.
2857 Also, these queues should be present until the last subscriber exits the system.
2858 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2859
2860 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2861 for each GEM in TECH PROFILE */
2862 key.id = queue_id_list[priority];
2863
2864 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2865 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2866 key.id = 0;
2867 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2868 }
2869 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2870 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2871 }
2872 else {
2873 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2874 }
2875
2876 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2877
2878 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2879 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
Girish Gowdra5287fde2021-07-31 00:41:45 +00002880 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002881
2882 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2883 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002884 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
Girish Gowdra72cbee92021-11-05 15:16:18 -07002885sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, tech_profile_id %d, err = %s (%d)\n", \
2886 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 +00002887 return err;
2888 }
2889
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302890 if (direction == upstream || direction == downstream) {
Thiyagarajan Subramani19168f52021-05-25 23:26:41 +05302891 Status st = install_gem_port(access_intf_id, onu_id, uni_id, gemport_id, board_technology);
Girish Gowdra252f4972020-09-07 21:24:01 -07002892 if (st.error_code() != grpc::StatusCode::ALREADY_EXISTS && st.error_code() != grpc::StatusCode::OK) {
2893 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);
2894 return BCM_ERR_INTERNAL;
2895 }
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002896 if (direction == upstream) {
2897 // Create the pon-gem to onu-uni mapping
2898 pon_gem pg(access_intf_id, gemport_id);
2899 onu_uni ou(onu_id, uni_id);
2900 bcmos_fastlock_lock(&pon_gem_to_onu_uni_map_lock);
2901 pon_gem_to_onu_uni_map[pg] = ou;
2902 bcmos_fastlock_unlock(&pon_gem_to_onu_uni_map_lock, 0);
2903 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002904 }
2905
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002906 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 +00002907intf_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 +00002908 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002909}
2910
Girish Gowdra252f4972020-09-07 21:24:01 -07002911Status CreateTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002912 uint32_t intf_id = traffic_queues->intf_id();
2913 uint32_t onu_id = traffic_queues->onu_id();
2914 uint32_t uni_id = traffic_queues->uni_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002915 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002916 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002917 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002918 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002919 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 +00002920
2921 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2922 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2923 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2924 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002925 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002926
2927 direction = GetDirection(traffic_queue.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002928 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002929 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002930 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002931
2932 queues_priority_q[i] = traffic_queue.priority();
2933 queues_pbit_map[i] = traffic_queue.pbit_map();
2934 }
2935
2936 std::vector<uint32_t> tmq_map_profile(8, 0);
2937 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2938 queues_priority_q, COUNT_OF(queues_priority_q));
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002939 sched_id = (direction == upstream) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002940 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002941
2942 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2943 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002944 err = CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2945 if (err != BCM_ERR_OK) {
2946 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2947 return bcm_to_grpc_err(err, "Failed to create tm queue mapping profile");
2948 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002949 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2950 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2951 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2952 }
2953 }
2954
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002955 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002956 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002957
2958 direction = GetDirection(traffic_queue.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002959 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002960 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002961 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002962
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002963 err = CreateQueue(direction, intf_id, onu_id, uni_id, qos_type, traffic_queue.priority(), traffic_queue.gemport_id(), tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002964
Girish Gowdruf26cf882019-05-01 23:47:58 -07002965 // If the queue exists already, lets not return failure and break the loop.
2966 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002967 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002968 return bcm_to_grpc_err(err, "Failed to create queue");
2969 }
2970 }
2971 return Status::OK;
2972}
2973
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002974bcmos_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 +00002975 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 +00002976 bcmolt_tm_queue_cfg cfg;
2977 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002978 bcmos_errno err;
2979
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302980 // Gemports are bi-directional (except in multicast case). We create the gem port when we create the
2981 // upstream/downstream queue (see CreateQueue function) and it makes sense to delete them when remove the queues.
2982 // For multicast case we do not manage the install/remove of gem port in agent application. It is managed by BAL.
2983 if (direction == upstream || direction == downstream) {
Thiyagarajan Subramani19168f52021-05-25 23:26:41 +05302984 Status st = remove_gem_port(access_intf_id, onu_id, uni_id, gemport_id, board_technology);
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302985 if (st.error_code() != grpc::StatusCode::OK) {
2986 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 -07002987 // We should further cleanup proceed, do not return error yet..
2988 // return BCM_ERR_INTERNAL;
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302989 }
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002990 if (direction == upstream) {
2991 // Remove the pon-gem to onu-uni mapping
2992 pon_gem pg(access_intf_id, gemport_id);
2993 bcmos_fastlock_lock(&pon_gem_to_onu_uni_map_lock);
2994 pon_gem_to_onu_uni_map.erase(pg);
2995 bcmos_fastlock_unlock(&pon_gem_to_onu_uni_map_lock, 0);
2996 }
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302997 }
2998
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002999 if (direction == downstream) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00003000 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction, tech_profile_id)) {
3001 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 +00003002 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003003 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003004 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 -08003005 return BCM_ERR_OK;
3006 }
3007 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003008 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
3009 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003010 return BCM_ERR_OK;
3011 }
3012
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003013 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
3014 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
3015 // Reset the queue id to 0 when using fixed queue.
3016 key.id = 0;
3017 }
3018 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
3019 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
3020 }
3021 else {
3022 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
3023 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003024
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003025 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
3026 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003027 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003028 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 -07003029tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s (%d)\n",
3030 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 -08003031 return err;
3032 }
3033
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003034 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
3035intf_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 -08003036
3037 return BCM_ERR_OK;
3038}
3039
Girish Gowdra252f4972020-09-07 21:24:01 -07003040Status RemoveTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003041 uint32_t intf_id = traffic_queues->intf_id();
3042 uint32_t onu_id = traffic_queues->onu_id();
3043 uint32_t uni_id = traffic_queues->uni_id();
3044 uint32_t port_no = traffic_queues->port_no();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00003045 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003046 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003047 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003048 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003049 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 -07003050 Status ret_code = Status::OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003051
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003052 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07003053 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003054
3055 direction = GetDirection(traffic_queue.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08003056 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003057 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08003058 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003059
Burak Gurdag2f2618c2020-04-23 13:20:30 +00003060 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 -08003061 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003062 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdra72cbee92021-11-05 15:16:18 -07003063 ret_code = bcm_to_grpc_err(err, "Failed to remove one or more queues");
3064 // Do not return here. We should continue to remove the remaining queues and its associated gem ports
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003065 }
Jonathan Davis70c21812018-07-19 15:32:10 -04003066 }
3067
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08003068 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE && (direction == upstream || \
3069 direction == downstream && is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id))) {
3070 sched_id = (direction == upstream) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00003071 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003072
3073 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
3074 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05003075 err = RemoveTrafficQueueMappingProfile(tm_qmp_id);
3076 if (err != BCM_ERR_OK) {
3077 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, err = %s\n", bcmos_strerror(err));
3078 return bcm_to_grpc_err(err, "Failed to remove tm queue mapping profile");
3079 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003080 }
3081 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003082 clear_qos_type(intf_id, onu_id, uni_id);
Girish Gowdra72cbee92021-11-05 15:16:18 -07003083 return ret_code;
Jonathan Davis70c21812018-07-19 15:32:10 -04003084}
Jason Huangbf45ffb2019-10-30 17:29:02 +08003085
Girish Gowdra252f4972020-09-07 21:24:01 -07003086Status PerformGroupOperation_(const ::openolt::Group *group_cfg) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003087
3088 bcmos_errno err;
3089 bcmolt_group_key key = {};
3090 bcmolt_group_cfg grp_cfg_obj;
3091 bcmolt_group_members_update grp_mem_upd;
3092 bcmolt_members_update_command grp_mem_upd_cmd;
3093 bcmolt_group_member_info member_info = {};
3094 bcmolt_group_member_info_list_u8 members = {};
3095 bcmolt_intf_ref interface_ref = {};
3096 bcmolt_egress_qos egress_qos = {};
3097 bcmolt_tm_sched_ref tm_sched_ref = {};
3098 bcmolt_action a_val = {};
3099
3100 uint32_t group_id = group_cfg->group_id();
3101
3102 OPENOLT_LOG(INFO, openolt_log_id, "PerformGroupOperation request received for Group %d\n", group_id);
3103
3104 if (group_id >= 0) {
3105 key.id = group_id;
3106 }
3107 else {
3108 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
3109 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
3110 }
3111
3112 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3113 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
3114
3115 OPENOLT_LOG(INFO, openolt_log_id, "Checking if Group %d exists...\n",group_id);
3116
3117 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
3118 if (err != BCM_ERR_OK) {
3119 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
3120 return bcm_to_grpc_err(err, "Error in querying group");
3121 }
3122
3123 members.len = group_cfg->members_size();
3124
3125 // IMPORTANT: A member cannot be added to a group if the group type is not determined.
3126 // Group type is determined after a flow is assigned to it.
3127 // Therefore, a group must be created first, then a flow (with multicast type) must be assigned to it.
3128 // Only then we can add members to the group.
3129
3130 // if group does not exist, create it and return.
3131 if (grp_cfg_obj.data.state == BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
3132
3133 if (members.len != 0) {
3134 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);
3135 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Non-empty member list given for non-existent group");
3136 } else {
3137
3138 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3139 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, cookie, key.id);
3140
3141 /* Setting group actions and action parameters, if any.
3142 Only remove_outer_tag and translate_inner_tag actions and i_vid action parameter
3143 are supported for multicast groups in BAL 3.1.
3144 */
3145 const ::openolt::Action& action = group_cfg->action();
3146 const ::openolt::ActionCmd &cmd = action.cmd();
3147
3148 bcmolt_action_cmd_id cmd_bmask = BCMOLT_ACTION_CMD_ID_NONE;
3149 if (cmd.remove_outer_tag()) {
3150 OPENOLT_LOG(INFO, openolt_log_id, "Action remove_outer_tag applied to Group %d.\n", group_id);
3151 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
3152 }
3153
3154 if (cmd.translate_inner_tag()) {
3155 OPENOLT_LOG(INFO, openolt_log_id, "Action translate_inner_tag applied to Group %d.\n", group_id);
3156 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG);
3157 }
3158
3159 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, cmd_bmask);
3160
3161 if (action.i_vid()) {
3162 OPENOLT_LOG(INFO, openolt_log_id, "Setting action parameter i_vid=%d for Group %d.\n", action.i_vid(), group_id);
3163 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
3164 }
3165
3166 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, action, a_val);
3167
3168 // Create group
3169 err = bcmolt_cfg_set(dev_id, &(grp_cfg_obj.hdr));
3170
3171 if (BCM_ERR_OK != err) {
3172 BCM_LOG(ERROR, openolt_log_id, "Failed to create Group %d, err = %s (%d)\n", key.id, bcmos_strerror(err), err);
3173 return bcm_to_grpc_err(err, "Error in creating group");
3174 }
3175
3176 BCM_LOG(INFO, openolt_log_id, "Group %d has been created and configured with empty member list.\n", key.id);
3177 return Status::OK;
3178 }
3179 }
3180
3181 // The group already exists. Continue configuring it according to the update member command.
3182
3183 OPENOLT_LOG(INFO, openolt_log_id, "Configuring existing Group %d.\n",group_id);
3184
3185 // MEMBER LIST CONSTRUCTION
3186 // Note that members.len can be 0 here. if the group already exists and the command is SET then sending
3187 // empty list to the group is a legit operation and this actually empties the member list.
3188 members.arr = (bcmolt_group_member_info*)bcmos_calloc((members.len)*sizeof(bcmolt_group_member_info));
3189
3190 if (!members.arr) {
3191 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to allocate memory for group member list.\n");
3192 return grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "Memory exhausted during member list creation");
3193 }
3194
3195 /* SET GROUP MEMBERS UPDATE COMMAND */
Girish Gowdra252f4972020-09-07 21:24:01 -07003196 ::openolt::Group::GroupMembersCommand command = group_cfg->command();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003197 switch(command) {
Girish Gowdra252f4972020-09-07 21:24:01 -07003198 case ::openolt::Group::SET_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003199 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_SET;
3200 OPENOLT_LOG(INFO, openolt_log_id, "Setting %d members for Group %d.\n", members.len, group_id);
3201 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003202 case ::openolt::Group::ADD_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003203 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_ADD;
3204 OPENOLT_LOG(INFO, openolt_log_id, "Adding %d members to Group %d.\n", members.len, group_id);
3205 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003206 case ::openolt::Group::REMOVE_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003207 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_REMOVE;
3208 OPENOLT_LOG(INFO, openolt_log_id, "Removing %d members from Group %d.\n", members.len, group_id);
3209 break;
3210 default :
3211 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid value %d for group member command.\n", command);
3212 bcmos_free(members.arr);
3213 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group member command");
3214 }
3215
3216 // SET MEMBERS LIST
3217 for (int i = 0; i < members.len; i++) {
3218
Girish Gowdra252f4972020-09-07 21:24:01 -07003219 if (command == ::openolt::Group::REMOVE_MEMBERS) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003220 OPENOLT_LOG(INFO, openolt_log_id, "Removing group member %d from group %d\n",i,key.id);
3221 } else {
3222 OPENOLT_LOG(INFO, openolt_log_id, "Adding group member %d to group %d\n",i,key.id);
3223 }
3224
Girish Gowdra252f4972020-09-07 21:24:01 -07003225 ::openolt::GroupMember *member = (::openolt::GroupMember *) &group_cfg->members()[i];
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003226
3227 // Set member interface type
Girish Gowdra252f4972020-09-07 21:24:01 -07003228 ::openolt::GroupMember::InterfaceType if_type = member->interface_type();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003229 switch(if_type){
Girish Gowdra252f4972020-09-07 21:24:01 -07003230 case ::openolt::GroupMember::PON :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003231 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_PON);
3232 OPENOLT_LOG(INFO, openolt_log_id, "Interface type PON is assigned to GroupMember %d\n",i);
3233 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003234 case ::openolt::GroupMember::EPON_1G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003235 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_1_G);
3236 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_1G is assigned to GroupMember %d\n",i);
3237 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003238 case ::openolt::GroupMember::EPON_10G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003239 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_10_G);
3240 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_10G is assigned to GroupMember %d\n",i);
3241 break;
3242 default :
3243 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid interface type value %d for GroupMember %d.\n",if_type,i);
3244 bcmos_free(members.arr);
3245 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface type for a group member");
3246 }
3247
3248 // Set member interface id
3249 if (member->interface_id() >= 0) {
3250 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_id, member->interface_id());
3251 OPENOLT_LOG(INFO, openolt_log_id, "Interface %d is assigned to GroupMember %d\n", member->interface_id(), i);
3252 } else {
3253 bcmos_free(members.arr);
3254 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface id for a group member");
3255 }
3256
3257 // Set member interface_ref
3258 BCMOLT_FIELD_SET(&member_info, group_member_info, intf, interface_ref);
3259
3260 // Set member gem_port_id. This must be a multicast gemport.
3261 if (member->gem_port_id() >= 0) {
3262 BCMOLT_FIELD_SET(&member_info, group_member_info, svc_port_id, member->gem_port_id());
3263 OPENOLT_LOG(INFO, openolt_log_id, "GEM Port %d is assigned to GroupMember %d\n", member->gem_port_id(), i);
3264 } else {
3265 bcmos_free(members.arr);
3266 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid gem port id for a group member");
3267 }
3268
3269 // Set member scheduler id and queue_id
3270 uint32_t tm_sched_id = get_default_tm_sched_id(member->interface_id(), downstream);
3271 OPENOLT_LOG(INFO, openolt_log_id, "Scheduler %d is assigned to GroupMember %d\n", tm_sched_id, i);
3272 BCMOLT_FIELD_SET(&tm_sched_ref, tm_sched_ref, id, tm_sched_id);
3273 BCMOLT_FIELD_SET(&egress_qos, egress_qos, tm_sched, tm_sched_ref);
3274
3275 // We assume that all multicast traffic destined to a PON port is using the same fixed queue.
3276 uint32_t tm_queue_id;
3277 if (member->priority() >= 0 && member->priority() < NUMBER_OF_DEFAULT_INTERFACE_QUEUES) {
3278 tm_queue_id = queue_id_list[member->priority()];
3279 OPENOLT_LOG(INFO, openolt_log_id, "Queue %d is assigned to GroupMember %d\n", tm_queue_id, i);
3280 BCMOLT_FIELD_SET(&egress_qos, egress_qos, type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
3281 BCMOLT_FIELD_SET(&egress_qos.u.fixed_queue, egress_qos_fixed_queue, queue_id, tm_queue_id);
3282 } else {
3283 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid fixed queue priority/ID %d for GroupMember %d\n", member->priority(), i);
3284 bcmos_free(members.arr);
3285 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid queue priority for a group member");
3286 }
3287
3288 BCMOLT_FIELD_SET(&member_info, group_member_info, egress_qos, egress_qos);
3289 BCMOLT_ARRAY_ELEM_SET(&(members), i, member_info);
3290 }
3291
3292 BCMOLT_OPER_INIT(&grp_mem_upd, group, members_update, key);
3293 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.members, members);
3294 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.command, grp_mem_upd_cmd);
3295
3296 err = bcmolt_oper_submit(dev_id, &(grp_mem_upd.hdr));
3297 bcmos_free(members.arr);
3298
3299 if (BCM_ERR_OK != err) {
3300 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);
3301 return bcm_to_grpc_err(err, "Failed to submit members update operation for the group");
3302 }
3303
3304 OPENOLT_LOG(INFO, openolt_log_id, "Successfully submitted members update operation for Group %d\n", key.id);
3305
3306 return Status::OK;
3307}
Burak Gurdageb4ca2e2020-06-15 07:48:26 +00003308
3309Status DeleteGroup_(uint32_t group_id) {
3310
3311 bcmos_errno err = BCM_ERR_OK;
3312 bcmolt_group_cfg grp_cfg_obj;
3313 bcmolt_group_key key = {};
3314
3315
3316 OPENOLT_LOG(INFO, openolt_log_id, "Delete request received for group %d\n", group_id);
3317
3318 if (group_id >= 0) {
3319 key.id = group_id;
3320 } else {
3321 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
3322 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
3323 }
3324
3325 /* init the BAL INIT API */
3326 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3327
3328 OPENOLT_LOG(DEBUG, openolt_log_id, "Checking if group %d exists...\n",group_id);
3329
3330 // CONFIGURE GROUP MEMBERS
3331 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
3332 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
3333
3334 if (err != BCM_ERR_OK) {
3335 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
3336 return bcm_to_grpc_err(err, "Error in querying group");
3337 }
3338
3339 if (grp_cfg_obj.data.state != BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
3340 OPENOLT_LOG(DEBUG, openolt_log_id, "Group %d exists. Will be deleted.\n",group_id);
3341 err = bcmolt_cfg_clear(dev_id, &(grp_cfg_obj.hdr));
3342 if (err != BCM_ERR_OK) {
3343 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d cannot be deleted err = %s (%d).\n", group_id, bcmos_strerror(err), err);
3344 return bcm_to_grpc_err(err, "Failed to delete group");;
3345 }
3346 } else {
3347 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d does not exist.\n", group_id);
3348 return Status(grpc::StatusCode::NOT_FOUND, "Group not found");
3349 }
3350
3351 OPENOLT_LOG(INFO, openolt_log_id, "Group %d has been deleted successfully.\n", group_id);
3352 return Status::OK;
Jason Huang1d9cfce2020-05-20 22:58:47 +08003353}
3354
Girish Gowdra252f4972020-09-07 21:24:01 -07003355Status GetLogicalOnuDistanceZero_(uint32_t intf_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003356 bcmos_errno err = BCM_ERR_OK;
3357 uint32_t mld = 0;
3358 double LD0;
3359
3360 err = getOnuMaxLogicalDistance(intf_id, &mld);
3361 if (err != BCM_ERR_OK) {
3362 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3363 }
3364
3365 LD0 = LOGICAL_DISTANCE(mld*1000, MINIMUM_ONU_RESPONSE_RANGING_TIME, ONU_BIT_TRANSMISSION_DELAY);
3366 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance zero is %f, (PON %d)\n", LD0, intf_id);
3367 response->set_intf_id(intf_id);
3368 response->set_logical_onu_distance_zero(LD0);
3369
3370 return Status::OK;
3371}
3372
Girish Gowdra252f4972020-09-07 21:24:01 -07003373Status GetLogicalOnuDistance_(uint32_t intf_id, uint32_t onu_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003374 bcmos_errno err = BCM_ERR_OK;
3375 bcmolt_itu_onu_params itu = {};
3376 bcmolt_onu_cfg onu_cfg;
3377 bcmolt_onu_key onu_key = {};
3378 uint32_t mld = 0;
3379 double LDi;
3380
3381 onu_key.pon_ni = intf_id;
3382 onu_key.onu_id = onu_id;
3383
3384 err = getOnuMaxLogicalDistance(intf_id, &mld);
3385 if (err != BCM_ERR_OK) {
3386 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3387 }
3388
3389 /* Initialize the API struct. */
3390 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
3391 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
3392 BCMOLT_FIELD_SET_PRESENT(&itu, itu_onu_params, ranging_time);
3393 BCMOLT_FIELD_SET(&onu_cfg.data, onu_cfg_data, itu, itu);
3394 #ifdef TEST_MODE
3395 // It is impossible to mock the setting of onu_cfg.data.onu_state because
3396 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
3397 // set the onu_cfg.data.onu_state. So a new stub function is created and address
3398 // of onu_cfg is passed. This is one-of case where we need to add test specific
3399 // code in production code.
3400 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
3401 #else
3402 /* Call API function. */
3403 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
3404 #endif
3405 if (err != BCM_ERR_OK) {
3406 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);
3407 return bcm_to_grpc_err(err, "Failed to retrieve ONU ranging time");
3408 }
3409
3410 if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_ACTIVE) {
3411 OPENOLT_LOG(ERROR, openolt_log_id, "ONU is not yet activated (PON %d, ONU id %d)\n", intf_id, onu_id);
3412 return bcm_to_grpc_err(BCM_ERR_PARM, "ONU is not yet activated\n");
3413 }
3414
3415 LDi = LOGICAL_DISTANCE(mld*1000, onu_cfg.data.itu.ranging_time, ONU_BIT_TRANSMISSION_DELAY);
3416 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance is %f, (PON %d, ONU id %d)\n", LDi, intf_id, onu_id);
3417 response->set_intf_id(intf_id);
3418 response->set_onu_id(onu_id);
3419 response->set_logical_onu_distance(LDi);
3420
3421 return Status::OK;
3422}
Burak Gurdag74e3ab82020-12-17 13:35:06 +00003423
3424Status GetOnuStatistics_(uint32_t intf_id, uint32_t onu_id, openolt::OnuStatistics* onu_stats) {
3425 bcmos_errno err;
3426
3427 err = get_onu_statistics((bcmolt_interface_id)intf_id, (bcmolt_onu_id)onu_id, onu_stats);
3428
3429 if (err != BCM_ERR_OK) {
3430 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));
3431 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of ONU statistics failed");
3432 }
3433
3434 OPENOLT_LOG(INFO, openolt_log_id, "retrieved ONU statistics for PON ID = %d, ONU ID = %d\n", (int)intf_id, (int)onu_id);
3435 return Status::OK;
3436}
3437
3438Status GetGemPortStatistics_(uint32_t intf_id, uint32_t gemport_id, openolt::GemPortStatistics* gemport_stats) {
3439 bcmos_errno err;
3440
3441 err = get_gemport_statistics((bcmolt_interface_id)intf_id, (bcmolt_gem_port_id)gemport_id, gemport_stats);
3442
3443 if (err != BCM_ERR_OK) {
3444 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));
3445 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of GEMPORT statistics failed");
3446 }
3447
3448 OPENOLT_LOG(INFO, openolt_log_id, "retrieved GEMPORT statistics for PON ID = %d, GEMPORT ID = %d\n", (int)intf_id, (int)gemport_id);
3449 return Status::OK;
3450}
Orhan Kupusogluec57af02021-05-12 12:38:17 +00003451
3452Status GetPonRxPower_(uint32_t intf_id, uint32_t onu_id, openolt::PonRxPowerData* response) {
3453 bcmos_errno err = BCM_ERR_OK;
3454
3455 // check the PON intf id
3456 if (intf_id >= MAX_SUPPORTED_PON) {
3457 err = BCM_ERR_PARM;
3458 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pon intf_id - intf_id: %d, onu_id: %d\n",
3459 intf_id, onu_id);
3460 return bcm_to_grpc_err(err, "invalid pon intf_id");
3461 }
3462
3463 bcmolt_onu_rssi_measurement onu_oper; /* declare main API struct */
3464 bcmolt_onu_key onu_key; /**< Object key. */
3465 onu_rssi_compltd_key key(intf_id, onu_id);
3466 Queue<onu_rssi_complete_result> queue;
3467
3468 OPENOLT_LOG(INFO, openolt_log_id, "GetPonRxPower - intf_id %d, onu_id %d\n", intf_id, onu_id);
3469
3470 onu_key.onu_id = onu_id;
3471 onu_key.pon_ni = intf_id;
3472 /* Initialize the API struct. */
3473 BCMOLT_OPER_INIT(&onu_oper, onu, rssi_measurement, onu_key);
3474 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
3475 if (err == BCM_ERR_OK) {
3476 // initialize map
3477 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3478 onu_rssi_compltd_map.insert({key, &queue});
3479 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3480 } else {
3481 OPENOLT_LOG(ERROR, openolt_log_id, "failed to measure rssi rx power - intf_id: %d, onu_id: %d, err = %s (%d): %s\n",
3482 intf_id, onu_id, bcmos_strerror(err), err, onu_oper.hdr.hdr.err_text);
3483 return bcm_to_grpc_err(err, "failed to measure rssi rx power");
3484 }
3485
3486 onu_rssi_complete_result completed{};
3487 if (!queue.pop(completed, ONU_RSSI_COMPLETE_WAIT_TIMEOUT)) {
3488 // invalidate the queue pointer
3489 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3490 onu_rssi_compltd_map[key] = NULL;
3491 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3492 err = BCM_ERR_TIMEOUT;
3493 OPENOLT_LOG(ERROR, openolt_log_id, "timeout waiting for RSSI Measurement Completed indication intf_id %d, onu_id %d\n",
3494 intf_id, onu_id);
3495 } else {
3496 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",
3497 completed.pon_intf_id, completed.onu_id, completed.status.c_str(), completed.reason, completed.rx_power_mean_dbm);
3498
3499 response->set_intf_id(completed.pon_intf_id);
3500 response->set_onu_id(completed.onu_id);
3501 response->set_status(completed.status);
3502 response->set_fail_reason(static_cast<::openolt::PonRxPowerData_RssiMeasurementFailReason>(completed.reason));
3503 response->set_rx_power_mean_dbm(completed.rx_power_mean_dbm);
3504 }
3505
3506 // Remove entry from map
3507 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3508 onu_rssi_compltd_map.erase(key);
3509 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3510
3511 if (err == BCM_ERR_OK) {
3512 return Status::OK;
3513 } else {
3514 return bcm_to_grpc_err(err, "timeout waiting for pon rssi measurement complete indication");
3515 }
3516}
nikesh.krishnan331d38c2023-04-06 03:24:53 +05303517
3518Status GetOnuInfo_(uint32_t intf_id, uint32_t onu_id, openolt::OnuInfo *response)
3519{
3520 bcmos_errno err = BCM_ERR_OK;
3521
3522 bcmolt_onu_state onu_state;
3523
3524 bcmolt_status losi;
3525 bcmolt_status lofi;
3526 bcmolt_status loami;
3527 err = get_gpon_onu_info((bcmolt_interface)intf_id, onu_id, &onu_state, &losi, &lofi, &loami);
3528
3529 if (err == BCM_ERR_OK)
3530 {
3531
3532 response->set_onu_id(onu_id);
3533 OPENOLT_LOG(DEBUG, openolt_log_id, "onu state %d\n", onu_state);
3534 OPENOLT_LOG(DEBUG, openolt_log_id, "losi %d\n", losi);
3535 OPENOLT_LOG(DEBUG, openolt_log_id, "lofi %d\n", lofi);
3536 OPENOLT_LOG(DEBUG, openolt_log_id, "loami %d\n", loami);
3537
3538 switch (onu_state)
3539 {
3540 case bcmolt_onu_state::BCMOLT_ONU_STATE_ACTIVE:
3541 response->set_state(openolt::OnuInfo_OnuState::OnuInfo_OnuState_ACTIVE);
3542 break;
3543 case bcmolt_onu_state::BCMOLT_ONU_STATE_INACTIVE:
3544 response->set_state(openolt::OnuInfo_OnuState::OnuInfo_OnuState_INACTIVE);
3545 break;
3546 case bcmolt_onu_state::BCMOLT_ONU_STATE_UNAWARE:
3547 response->set_state(openolt::OnuInfo_OnuState::OnuInfo_OnuState_UNKNOWN);
3548 break;
3549 case bcmolt_onu_state::BCMOLT_ONU_STATE_NOT_CONFIGURED:
3550 response->set_state(openolt::OnuInfo_OnuState::OnuInfo_OnuState_NOT_CONFIGURED);
3551 break;
3552 case bcmolt_onu_state::BCMOLT_ONU_STATE_DISABLED:
3553 response->set_state(openolt::OnuInfo_OnuState::OnuInfo_OnuState_DISABLED);
3554 break;
3555 }
3556 switch (losi)
3557 {
3558 case bcmolt_status::BCMOLT_STATUS_ON:
3559 response->set_losi(openolt::AlarmState::ON);
3560 break;
3561 case bcmolt_status::BCMOLT_STATUS_OFF:
3562 response->set_losi(openolt::AlarmState::OFF);
3563 break;
3564 }
3565
3566 switch (lofi)
3567 {
3568 case bcmolt_status::BCMOLT_STATUS_ON:
3569 response->set_lofi(openolt::AlarmState::ON);
3570 break;
3571 case bcmolt_status::BCMOLT_STATUS_OFF:
3572 response->set_lofi(openolt::AlarmState::OFF);
3573 break;
3574 }
3575
3576 switch (loami)
3577 {
3578 case bcmolt_status::BCMOLT_STATUS_ON:
3579 response->set_loami(openolt::AlarmState::ON);
3580 break;
3581 case bcmolt_status::BCMOLT_STATUS_OFF:
3582 response->set_loami(openolt::AlarmState::OFF);
3583 break;
3584 }
3585 return Status::OK;
3586 }
3587 else
3588 {
3589 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch Onu status, onu_id = %d, intf_id = %d, err = %s\n",
3590 onu_id, intf_id, bcmos_strerror(err));
3591 return bcm_to_grpc_err(err, "Failed to fetch Onu status");
3592 }
3593}
3594
3595Status GetPonInterfaceInfo_(uint32_t intf_id, openolt::PonIntfInfo *response)
3596{
3597 bcmos_errno err = BCM_ERR_OK;
3598
3599 bcmolt_status los_status;
3600 bcmolt_interface_state state;
3601 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
3602 OPENOLT_LOG(ERROR, openolt_log_id, "pon state %d\n",state);
3603 OPENOLT_LOG(ERROR, openolt_log_id, "pon los status %d\n", los_status);
3604
3605
3606 if (err == BCM_ERR_OK)
3607 {
3608 response->set_intf_id(intf_id) ;
3609 switch (los_status)
3610 {
3611 case bcmolt_status::BCMOLT_STATUS_ON:
3612
3613 response->set_los(openolt::AlarmState::ON);
3614 break;
3615 case bcmolt_status::BCMOLT_STATUS_OFF:
3616 response->set_los(openolt::AlarmState::OFF);
3617 break;
3618 }
3619
3620 switch (state)
3621 {
3622 case bcmolt_interface_state::BCMOLT_INTERFACE_STATE_ACTIVE_WORKING:
3623 response->set_state(openolt::PonIntfInfo_PonIntfState::PonIntfInfo_PonIntfState_ACTIVE_WORKING);
3624 break;
3625 case bcmolt_interface_state::BCMOLT_INTERFACE_STATE_ACTIVE_STANDBY:
3626 response->set_state(openolt::PonIntfInfo_PonIntfState::PonIntfInfo_PonIntfState_ACTIVE_STANDBY);
3627 break;
3628
3629 case bcmolt_interface_state::BCMOLT_INTERFACE_STATE_DISABLED:
3630 response->set_state(openolt::PonIntfInfo_PonIntfState::PonIntfInfo_PonIntfState_DISABLED);
3631 break;
3632
3633 case bcmolt_interface_state::BCMOLT_INTERFACE_STATE_INACTIVE:
3634
3635 response->set_state(openolt::PonIntfInfo_PonIntfState::PonIntfInfo_PonIntfState_INACTIVE);
3636 break;
3637 default:
3638 response->set_state(openolt::PonIntfInfo_PonIntfState::PonIntfInfo_PonIntfState_UNKNOWN);
3639 }
3640
3641 return Status::OK;
3642 }
3643 else
3644 {
3645 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch PON interface los status intf_id = %d, err = %s\n",
3646 intf_id, bcmos_strerror(err));
3647 return bcm_to_grpc_err(err, "Failed to fetch PON interface los status intf_id");
3648 }
3649}