blob: 28b7a4b202bb69d76dc7f2c5c83172016939a572 [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);
931 }
932
Girish Gowdrab0337eb2022-03-25 16:44:21 -0700933 // TODO: Currently the PON Type is set automatically when the MAC System Mode is set. But it could be explicitely set here again.
934 // The data for the PON type is availabe in the PonTrx object (check trx_data)
935
kesavandc1f2db92020-08-31 15:32:06 +0530936 //Enable AES Encryption
937 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.key_exchange, BCMOLT_CONTROL_STATE_ENABLE);
938 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.authentication, BCMOLT_CONTROL_STATE_ENABLE);
939 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.fail_due_to_authentication_failure, BCMOLT_CONTROL_STATE_ENABLE);
940
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000941 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
942 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
943
944 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
945 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500946 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 +0000947 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
948 }
949 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
950 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500951 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 +0000952 return bcm_to_grpc_err(err, "Failed to enable PON interface");
953 }
954 else {
955 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
956 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
957 CreateDefaultSched(intf_id, downstream);
958 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400959 }
960
961 return Status::OK;
962}
963
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500964Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000965 bcmos_errno err;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400966 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000967 bcmolt_device_key dev_key = { };
968 bcmolt_olt_cfg olt_cfg = { };
969 bcmolt_olt_key olt_key = { };
970 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
971 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500972
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000973 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
974 topo.topology_maps.arr = &topo_map[0];
975 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
976 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
977 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400978 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000979 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400980 #ifdef TEST_MODE
981 // It is impossible to mock the setting of olt_cfg.data.bal_state because
982 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
983 // set the olt_cfg.data.topology. So a new stub function is created and address
984 // of olt_cfg is passed. This is one-of case where we need to test add specific
985 // code in production code.
986 err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
987 #else
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000988 err = bcmolt_cfg_get_mult_retry(dev_id, &olt_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400989 #endif
990 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500991 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 +0000992 return bcm_to_grpc_err(err, "cfg: Failed to query OLT topology");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500993 }
994
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000995 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
996 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500997
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400998 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
999 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001000 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001001
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001002 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
1003 num_of_nni_ports,
1004 num_of_pon_ports,
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001005 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001006
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001007 uint32_t num_failed_cfg_gets = 0;
Jason Huang09b73ea2020-01-08 17:52:05 +08001008 static std::string openolt_version = firmware_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001009 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
1010 dev_key.device_id = devid;
1011 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
1012 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
1013 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
1014 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001015 err = bcmolt_cfg_get_mult_retry(dev_id, &dev_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001016 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001017 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 +00001018 num_failed_cfg_gets++;
1019 continue;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001020 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001021
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001022 std::string bal_version;
1023 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
1024 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
1025 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
Jason Huang09b73ea2020-01-08 17:52:05 +08001026 firmware_version = "BAL." + bal_version + "__" + openolt_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001027
1028 switch(dev_cfg.data.system_mode) {
1029 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
1030 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
1031 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
1032 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
1033 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
1034 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
1035 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
1036 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
1037 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
1038 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 +08001039 case 38:
1040 board_technology = "XGS-PON";
1041 FILL_ARRAY2(intf_technologies,devid*16,(devid+1)*16,"XGS-PON");
1042 FILL_ARRAY2(intf_technologies,devid*16+1,(devid+1)*16+1,"GPON");
1043 break;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001044 }
1045
1046 switch(dev_cfg.data.chip_family) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001047 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X: chip_family = "Maple"; break;
1048 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X: chip_family = "Aspen"; break;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001049 }
1050
Jason Huang09b73ea2020-01-08 17:52:05 +08001051 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s, family: %s, board_technology: %s\n",
1052 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 +00001053
1054 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001055 }
1056
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001057 /* 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 +00001058 only the devices that retured success*/
1059 if (num_failed_cfg_gets == BCM_MAX_DEVS_PER_LINE_CARD) {
1060 OPENOLT_LOG(ERROR, openolt_log_id, "device: Query of all the devices failed\n");
1061 return bcm_to_grpc_err(err, "device: All devices failed query");
1062 }
1063
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001064 return Status::OK;
1065}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001066
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001067Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001068 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001069 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
1070 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
1071 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001072
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001073 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001074 if (err == BCM_ERR_OK) {
1075 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001076 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001077 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1078 CreateDefaultSched(intf_id, upstream);
1079 CreateDefaultQueue(intf_id, upstream);
1080 return Status::OK;
1081 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1082 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
1083 return Status::OK;
1084 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001085 }
1086
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001087 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
1088 if (set_state) {
1089 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1090 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1091 } else {
1092 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1093 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1094 }
1095 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
1096 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001097 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err = %s\n",
1098 (set_state)?"enable":"disable", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001099 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
1100 }
1101 else {
1102 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
1103 if (set_state) {
1104 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1105 CreateDefaultSched(intf_id, upstream);
1106 CreateDefaultQueue(intf_id, upstream);
1107 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001108 }
1109
1110 return Status::OK;
1111}
1112
Elia Battiston869a5de2022-02-08 11:40:58 +01001113uint32_t GetNniSpeed_(uint32_t intf_id) {
1114 bcmos_errno err = BCM_ERR_OK;
1115
1116 uint32_t speed;
1117 err = get_nni_interface_speed((bcmolt_interface)intf_id, &speed);
1118 if (err != BCM_ERR_OK) {
1119 OPENOLT_LOG(WARNING, openolt_log_id, "Failed to read speed of NNI interface: %d\n", intf_id);
1120 return 0; //This will cause the adapter to use the default speed value
1121 }
1122
1123 return speed;
1124}
1125
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001126Status DisablePonIf_(uint32_t intf_id) {
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001127 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001128 bcmolt_pon_interface_cfg interface_obj;
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001129 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1130 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001131
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001132 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
Girish Gowdrae1db2952021-05-04 00:16:54 -07001133 BCMOLT_MSG_FIELD_GET(&interface_obj, state);
1134
1135 err = bcmolt_cfg_get(dev_id, &interface_obj.hdr);
1136 if (err != BCM_ERR_OK) {
1137 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);
1138 return bcm_to_grpc_err(err, "Failed to fetch pon port state");
1139 }
1140 if (interface_obj.data.state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1141 OPENOLT_LOG(INFO, openolt_log_id, "PON Interface already inactive, PON interface %d\n", intf_id);
1142 return Status::OK;
1143 }
1144
1145 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001146 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1147 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_DISABLE);
1148
1149 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1150 if (err != BCM_ERR_OK) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07001151 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 -05001152 return bcm_to_grpc_err(err, "Failed to disable discovery of onu");
1153 }
1154
1155 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1156 operation, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1157
1158 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1159 if (err != BCM_ERR_OK) {
1160 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 -04001161 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001162 }
1163
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001164 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled PON interface: %d\n", intf_id);
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001165 return Status::OK;
1166}
1167
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001168Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
kesavandc1f2db92020-08-31 15:32:06 +05301169 const char *vendor_id, const char *vendor_specific, uint32_t pir, bool omcc_encryption_mode) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001170 bcmos_errno err = BCM_ERR_OK;
1171 bcmolt_onu_cfg onu_cfg;
1172 bcmolt_onu_key onu_key;
Shivanagouda Malaginahallie707d612023-08-22 10:40:25 +00001173 bcmolt_serial_number serial_number = {}; /**< ONU serial number */
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001174 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001175
Girish Gowdra24297032020-03-23 12:32:37 -07001176 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1177 bcmolt_onu_state onu_state;
1178
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001179 onu_key.onu_id = onu_id;
1180 onu_key.pon_ni = intf_id;
1181 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1182 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Girish Gowdra24297032020-03-23 12:32:37 -07001183#ifdef TEST_MODE
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001184 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1185 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1186 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1187 // of onu_cfg is passed. This is one-of case where we need to add test specific
1188 // code in production code.
1189 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Girish Gowdra24297032020-03-23 12:32:37 -07001190#else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001191 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Girish Gowdra24297032020-03-23 12:32:37 -07001192#endif
1193 OPENOLT_LOG(INFO, openolt_log_id, "Activate ONU : old state = %d, current state = %d\n",
1194 onu_cfg.data.onu_old_state, onu_cfg.data.onu_state);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001195 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001196 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) {
1197 OPENOLT_LOG(INFO, openolt_log_id, "ONU is already in ACTIVE state, \
1198not processing this request for pon_intf=%d onu_id=%d\n", intf_id, onu_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001199 return Status::OK;
Girish Gowdra24297032020-03-23 12:32:37 -07001200 } else if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_NOT_CONFIGURED &&
1201 onu_cfg.data.onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1202 // We need the ONU to be in NOT_CONFIGURED or INACTIVE state to further process the request
1203 OPENOLT_LOG(ERROR, openolt_log_id, "ONU in an invalid state to process the request, \
1204state=%d pon_intf=%d onu_id=%d\n", onu_cfg.data.onu_state, intf_id, onu_id);
1205 return bcm_to_grpc_err(err, "Failed to activate ONU, invalid ONU state");
1206 }
1207 } else {
1208 // This should never happen. BAL GET should succeed for non-existant ONUs too. The state of such ONUs will be NOT_CONFIGURED
1209 OPENOLT_LOG(ERROR, openolt_log_id, "ONU state query failed pon_intf=%d onu_id=%d\n", intf_id, onu_id);
1210 return bcm_to_grpc_err(err, "onu get failed");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001211 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001212
Girish Gowdra24297032020-03-23 12:32:37 -07001213 // If the ONU is not configured at all we need to first configure it
1214 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_NOT_CONFIGURED) {
1215 OPENOLT_LOG(INFO, openolt_log_id, "Configuring ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001216vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Girish Gowdra24297032020-03-23 12:32:37 -07001217 vendor_specific_to_str(vendor_specific).c_str(), pir);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001218
Girish Gowdra24297032020-03-23 12:32:37 -07001219 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1220 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
Shivanagouda Malaginahallie707d612023-08-22 10:40:25 +00001221
Girish Gowdra24297032020-03-23 12:32:37 -07001222 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1223 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1224 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1225 /*set burst and data profiles to fec disabled*/
Arthur Syu094df162022-04-21 17:50:06 +08001226 std::string intf_technology = intf_technologies[intf_id];
1227 if (intf_technology == "XGS-PON") {
Girish Gowdra24297032020-03-23 12:32:37 -07001228 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1229 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
Arthur Syu094df162022-04-21 17:50:06 +08001230 } else if (intf_technology == "GPON") {
Girish Gowdra24297032020-03-23 12:32:37 -07001231 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1232 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1233 }
1234 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1235 if (err != BCM_ERR_OK) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07001236 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 -07001237 return bcm_to_grpc_err(err, "Failed to configure ONU");
1238 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001239 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001240
Burak Gurdaga0523592021-02-24 15:17:47 +00001241// TODO: MOVE THIS TO A NEW METHOD
kesavandc1f2db92020-08-31 15:32:06 +05301242 if (omcc_encryption_mode == true) {
1243 // set the encryption mode for omci port id
1244 bcmolt_itupon_gem_cfg gem_cfg;
1245 bcmolt_itupon_gem_key key = {};
1246 bcmolt_gem_port_configuration configuration = {};
1247 key.pon_ni = intf_id;
1248 key.gem_port_id = onu_id;
1249 bcmolt_control_state encryption_mode;
1250 encryption_mode = BCMOLT_CONTROL_STATE_ENABLE;
1251 BCMOLT_CFG_INIT(&gem_cfg, itupon_gem, key);
1252 BCMOLT_FIELD_SET(&gem_cfg.data, itupon_gem_cfg_data, encryption_mode, encryption_mode);
1253 err = bcmolt_cfg_set(dev_id, &gem_cfg.hdr);
1254 if(err != BCM_ERR_OK) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07001255 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 +05301256 return bcm_to_grpc_err(err, "Access_Control set ITU PON OMCI Gem port failed");
1257 }
1258 }
Girish Gowdra24297032020-03-23 12:32:37 -07001259 // Now that the ONU is configured, move the ONU to ACTIVE state
1260 memset(&onu_cfg, 0, sizeof(bcmolt_onu_cfg));
1261 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1262 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1263 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
1264 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
1265 onu_state, BCMOLT_ONU_OPERATION_ACTIVE);
1266 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001267 if (err != BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001268 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 +00001269 return bcm_to_grpc_err(err, "Failed to activate ONU");
1270 }
Girish Gowdra24297032020-03-23 12:32:37 -07001271 // ONU will eventually get activated after we have submitted the operation request. The adapter will receive an asynchronous
1272 // ONU_ACTIVATION_COMPLETED_INDICATION
1273
1274 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 +00001275
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001276 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001277}
1278
Jonathan Davis70c21812018-07-19 15:32:10 -04001279Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1280 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001281 bcmos_errno err = BCM_ERR_OK;
1282 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1283 bcmolt_onu_cfg onu_cfg;
1284 bcmolt_onu_key onu_key; /**< Object key. */
1285 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001286
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001287 onu_key.onu_id = onu_id;
1288 onu_key.pon_ni = intf_id;
1289 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1290 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1291 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301292 onu_state = onu_cfg.data.onu_state;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001293 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001294 switch (onu_state) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001295 case BCMOLT_ONU_STATE_ACTIVE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001296 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001297 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001298 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1299 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1300 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001301 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 +00001302 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1303 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301304 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 +00001305 break;
1306 }
Girish Gowdra72cbee92021-11-05 15:16:18 -07001307 } else {
1308 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to deactivate ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
1309 return bcm_to_grpc_err(err, "Failed to get onu config");
Jonathan Davis70c21812018-07-19 15:32:10 -04001310 }
1311
1312 return Status::OK;
1313}
1314
1315Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001316 const char *vendor_id, const char *vendor_specific) {
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301317 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301318 bcmolt_onu_state onu_state;
Girish Gowdra72cbee92021-11-05 15:16:18 -07001319 Status st;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001320
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001321 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 -05001322 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1323
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001324 // Need to deactivate before removing it (BAL rules)
Girish Gowdra72cbee92021-11-05 15:16:18 -07001325 st = DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
1326 if (st.error_code() != grpc::StatusCode::OK) {
1327 return st;
1328 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301329
Girish Gowdra72cbee92021-11-05 15:16:18 -07001330 err = get_onu_state((bcmolt_interface)intf_id, onu_id, &onu_state);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301331 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001332 if (onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1333 OPENOLT_LOG(INFO, openolt_log_id, "waiting for onu deactivate complete response: intf_id=%d, onu_id=%d\n",
1334 intf_id, onu_id);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301335 err = wait_for_onu_deactivate_complete(intf_id, onu_id);
1336 if (err) {
1337 OPENOLT_LOG(ERROR, openolt_log_id, "failed to delete onu intf_id %d, onu_id %d\n",
1338 intf_id, onu_id);
1339 return bcm_to_grpc_err(err, "Failed to delete ONU");
1340 }
1341 }
Girish Gowdra24297032020-03-23 12:32:37 -07001342 else {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301343 OPENOLT_LOG(INFO, openolt_log_id, "Onu is Inactive, onu_id: %d, not waiting for onu deactivate complete response\n",
1344 intf_id);
1345 }
1346 }
1347 else {
1348 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch Onu status, onu_id = %d, intf_id = %d, err = %s\n",
1349 onu_id, intf_id, bcmos_strerror(err));
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301350 return bcm_to_grpc_err(err, "Failed to delete ONU");
1351 }
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001352
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001353 bcmolt_onu_cfg cfg_obj;
1354 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001355
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001356 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 -04001357 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001358
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001359 key.onu_id = onu_id;
1360 key.pon_ni = intf_id;
1361 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001362
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301363 err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001364 if (err != BCM_ERR_OK)
1365 {
Girish Gowdra72cbee92021-11-05 15:16:18 -07001366 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 -04001367 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1368 }
1369
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301370 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 +00001371 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001372}
1373
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001374#define MAX_CHAR_LENGTH 20
1375#define MAX_OMCI_MSG_LENGTH 44
1376Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001377 bcmolt_bin_str buf = {};
1378 bcmolt_onu_cpu_packets omci_cpu_packets;
1379 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001380
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001381 key.pon_ni = intf_id;
1382 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001383
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001384 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1385 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1386 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001387
1388 // ???
1389 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1390 buf.len = MAX_OMCI_MSG_LENGTH;
1391 } else {
1392 buf.len = pkt.size()/2;
1393 }
1394
1395 /* Send the OMCI packet using the BAL remote proxy API */
1396 uint16_t idx1 = 0;
1397 uint16_t idx2 = 0;
1398 uint8_t arraySend[buf.len];
1399 char str1[MAX_CHAR_LENGTH];
1400 char str2[MAX_CHAR_LENGTH];
1401 memset(&arraySend, 0, buf.len);
1402
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001403 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1404 sprintf(str1,"%c", pkt[idx1]);
1405 sprintf(str2,"%c", pkt[++idx1]);
1406 strcat(str1,str2);
1407 arraySend[idx2] = strtol(str1, NULL, 16);
1408 }
1409
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001410 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1411 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001412
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001413 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1414 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1415 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001416
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001417 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001418 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001419 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 +00001420 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001421 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001422 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 -05001423 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001424 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001425 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001426
1427 return Status::OK;
1428}
1429
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001430Status 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 +00001431 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1432 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1433 bcmolt_bin_str buf = {};
1434 bcmolt_gem_port_id gem_port_id_array[1];
1435 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001436
Craig Lutgen967a1d02018-11-27 10:41:51 -06001437 if (port_no > 0) {
1438 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001439 if (gemport_id == 0) {
1440 bcmos_fastlock_lock(&data_lock);
1441 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1442 // Pick any flow that is mapped with the same port_no.
1443 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1444 if (it != port_to_flows.end() && !it->second.empty()) {
1445 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1446 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1447 if (fit != flowid_to_gemport.end()) {
1448 found = true;
1449 gemport_id = fit->second;
1450 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001451 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001452 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001453
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001454 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001455 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 -08001456 onu_id, port_no, intf_id);
1457 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1458 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001459 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 -08001460 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001461 }
1462
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001463 gem_port_id_array[0] = gemport_id;
1464 gem_port_list.len = 1;
1465 gem_port_list.arr = gem_port_id_array;
1466 buf.len = pkt.size();
1467 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1468 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1469
1470 /* init the API struct */
1471 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1472 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1473 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1474 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1475 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1476
1477 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1478 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1479
1480 /* call API */
1481 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001482 }
1483 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001484 //TODO: Port No is 0, it is coming sender requirement.
1485 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1486 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001487 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001488 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001489
1490 return Status::OK;
1491}
1492
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001493Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001494 bcmolt_flow_key key = {}; /* declare key */
1495 bcmolt_bin_str buffer = {};
1496 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001497
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001498 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
Girish Gowdra252f4972020-09-07 21:24:01 -07001499 bcmolt_flow_id flow_id = INVALID_FLOW_ID;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001500
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001501 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1502 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1503 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1504 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1505 key.flow_id = flow_id;
1506 else {
Jason Huang09b73ea2020-01-08 17:52:05 +08001507 if (flow_id_counters) {
1508 std::map<flow_pair, int>::iterator it;
1509 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1510 int flow_index = it->first.first;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001511 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1512 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1513 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1514 key.flow_id = flow_index;
1515 break;
1516 }
1517 }
1518 }
1519 else {
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001520 OPENOLT_LOG(ERROR, openolt_log_id, "no flow id found for uplink packetout\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001521 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1522 }
1523 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001524
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001525 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001526
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001527 /* Initialize the API struct. */
1528 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001529
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001530 buffer.len = pkt.size();
1531 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1532 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1533 if (buffer.arr == NULL) {
1534 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1535 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1536 }
1537 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1538
1539 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1540 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001541 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 -05001542 return bcm_to_grpc_err(BCM_ERR_SYSCALL_ERR, "Error sending packets via nni port");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001543 } else {
1544 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1545 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001546
1547 return Status::OK;
1548}
Girish Gowdra252f4972020-09-07 21:24:01 -07001549
Burak Gurdaga0523592021-02-24 15:17:47 +00001550bool get_aes_flag_for_gem_port(const google::protobuf::Map<unsigned int, bool> &gemport_to_aes, uint32_t gemport_id) {
1551 bool aes_flag = false;
1552 for (google::protobuf::Map<unsigned int, bool>::const_iterator it=gemport_to_aes.begin(); it!=gemport_to_aes.end(); it++) {
1553 if (it->first == gemport_id) {
1554 aes_flag = it->second;
1555 break;
1556 }
1557 }
1558 return aes_flag;
1559}
1560
Girish Gowdra252f4972020-09-07 21:24:01 -07001561Status FlowAddWrapper_(const ::openolt::Flow* request) {
1562
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001563 Status st = Status::OK;
Girish Gowdra252f4972020-09-07 21:24:01 -07001564 int32_t access_intf_id = request->access_intf_id();
1565 int32_t onu_id = request->onu_id();
1566 int32_t uni_id = request->uni_id();
1567 uint32_t port_no = request->port_no();
1568 uint64_t voltha_flow_id = request->flow_id();
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001569 uint64_t symmetric_voltha_flow_id = 0;
Girish Gowdra252f4972020-09-07 21:24:01 -07001570 const std::string flow_type = request->flow_type();
1571 int32_t alloc_id = request->alloc_id();
1572 int32_t network_intf_id = request->network_intf_id();
1573 int32_t gemport_id = request->gemport_id();
1574 const ::openolt::Classifier& classifier = request->classifier();
1575 const ::openolt::Action& action = request->action();
1576 int32_t priority = request->priority();
1577 uint64_t cookie = request->cookie();
1578 int32_t group_id = request->group_id();
1579 uint32_t tech_profile_id = request->tech_profile_id();
1580 bool replicate_flow = request->replicate_flow();
1581 const google::protobuf::Map<unsigned int, unsigned int> &pbit_to_gemport = request->pbit_to_gemport();
Burak Gurdaga0523592021-02-24 15:17:47 +00001582 const google::protobuf::Map<unsigned int, bool> &gemport_to_aes = request->gemport_to_aes();
Girish Gowdra252f4972020-09-07 21:24:01 -07001583 uint16_t flow_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001584 bool enable_encryption;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001585 // When following conditions are ALL met, it qualifies as datapath flow.
1586 // 1. valid access_intf_id, onu_id, uni_id
1587 // 2. Valid tech_profile_id
1588 // 3. flow_type that is not MULTICAST
1589 // 4. Not a trap-to-host flow.
1590 bool datapathFlow = access_intf_id >= 0 && onu_id >= 0 && uni_id >= 0 && tech_profile_id > 0
1591 && flow_type != multicast && !action.cmd().trap_to_host();
1592
1593 if (datapathFlow) {
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08001594 const std::string inverse_flow_type = flow_type == upstream? downstream : upstream;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001595 symmetric_datapath_flow_id_map_key key(access_intf_id, onu_id, uni_id, tech_profile_id, inverse_flow_type);
1596 // Find the onu-uni mapping for the pon-gem key
1597 bcmos_fastlock_lock(&symmetric_datapath_flow_id_lock);
1598 auto it = symmetric_datapath_flow_id_map.find(key);
1599 bcmos_fastlock_unlock(&symmetric_datapath_flow_id_lock, 0);
1600 if (it != symmetric_datapath_flow_id_map.end()) {
1601 symmetric_voltha_flow_id = it->second;
1602 }
1603 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001604
1605 // The intf_id variable defaults to access(PON) interface ID.
1606 // For trap-from-nni flow where access interface ID is not valid , change it to NNI interface ID
1607 // This intf_id identifies the pool from which we get the flow_id
1608 uint32_t intf_id = access_intf_id;
1609 if (onu_id < 1) {
1610 onu_id = 1;
1611 }
1612 if (access_intf_id < 0) {
1613 intf_id = network_intf_id;
1614 }
1615
1616 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)
1617 // This is the case of voltha_flow_id (not symmetric_voltha_flow_id)
1618 if (is_voltha_flow_installed(voltha_flow_id)) {
1619 OPENOLT_LOG(INFO, openolt_log_id, "voltha_flow_id=%lu, already installed\n", voltha_flow_id);
1620 return ::Status(grpc::StatusCode::ALREADY_EXISTS, "voltha-flow-already-installed");
1621 }
1622
Girish Gowdra252f4972020-09-07 21:24:01 -07001623 // This is the case of symmetric_voltha_flow_id
1624 // If symmetric_voltha_flow_id is available and valid in the Flow message,
1625 // check if it is installed, and use the corresponding device_flow_id
1626 if (symmetric_voltha_flow_id > 0 && is_voltha_flow_installed(symmetric_voltha_flow_id)) { // symmetric flow found
1627 OPENOLT_LOG(INFO, openolt_log_id, "symmetric flow and the symmetric flow is installed\n");
1628 const device_flow_params *dev_fl_symm_params;
1629 dev_fl_symm_params = get_device_flow_params(symmetric_voltha_flow_id);
1630 if (dev_fl_symm_params == NULL) {
1631 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)
1632 return ::Status(grpc::StatusCode::INTERNAL, "symmetric-flow-details-not-found");
1633 }
1634
1635 if (!replicate_flow) { // No flow replication
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001636 flow_id = dev_fl_symm_params[0].flow_id;
1637 gemport_id = dev_fl_symm_params[0].gemport_id; // overwrite the gemport with symmetric flow gemport
1638 // Should be same as what is coming in this request.
1639 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
1640 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1641 cl.set_o_pbits(dev_fl_symm_params[0].pbit);
1642 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1643 flow_type, alloc_id, network_intf_id, gemport_id, cl,
1644 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
1645 if (st.error_code() != grpc::StatusCode::OK && st.error_code() != grpc::StatusCode::ALREADY_EXISTS) {
1646 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 -07001647 free_flow_id(flow_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001648 return st;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001649 }
1650
1651 device_flow dev_fl;
1652 dev_fl.is_flow_replicated = false;
1653 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1654 dev_fl.voltha_flow_id = voltha_flow_id;
Girish Gowdra72bb4652022-01-18 17:04:30 -08001655 dev_fl.flow_type = flow_type;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001656 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params));
1657 // update voltha flow to cache
1658 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
Girish Gowdra252f4972020-09-07 21:24:01 -07001659 } else { // Flow to be replicated
1660 OPENOLT_LOG(INFO, openolt_log_id,"symmetric flow and replication is needed\n");
Girish Gowdra52997cc2022-06-02 20:58:50 -07001661 if (pbit_to_gemport.size() > NUMBER_OF_PBITS) {
1662 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pbit-to-gemport map size=%lu", pbit_to_gemport.size())
1663 return ::Status(grpc::StatusCode::OUT_OF_RANGE, "pbit-to-gemport-map-len-invalid-for-flow-replication");
1664 }
1665 for (uint8_t i=0; i<pbit_to_gemport.size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07001666 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1667 flow_id = dev_fl_symm_params[i].flow_id;
1668 gemport_id = dev_fl_symm_params[i].gemport_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001669 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001670 cl.set_o_pbits(dev_fl_symm_params[i].pbit);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001671 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdrade65ab42020-12-17 23:08:43 -08001672 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001673 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001674 if (st.error_code() != grpc::StatusCode::OK && st.error_code() != grpc::StatusCode::ALREADY_EXISTS) {
1675 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);
1676 // On failure remove any successfully replicated flows installed so far for the voltha_flow_id
1677 if (i > 0) {
1678 for (int8_t j = i-1; j >= 0; j--) {
1679 flow_id = dev_fl_symm_params[j].flow_id;
1680 FlowRemove_(flow_id, flow_type);
1681 }
1682 }
Girish Gowdra72cbee92021-11-05 15:16:18 -07001683 // Note: We should not free the flow_ids here because the symmetric flow is already using that flow id.
1684 // 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 -07001685 return st;
1686 }
1687 }
1688 device_flow dev_fl;
1689 dev_fl.is_flow_replicated = true;
1690 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1691 dev_fl.voltha_flow_id = voltha_flow_id;
Girish Gowdra52997cc2022-06-02 20:58:50 -07001692 dev_fl.total_replicated_flows = pbit_to_gemport.size();
Girish Gowdra72bb4652022-01-18 17:04:30 -08001693 dev_fl.flow_type = flow_type;
Girish Gowdra52997cc2022-06-02 20:58:50 -07001694 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params)*dev_fl.total_replicated_flows);
Girish Gowdra252f4972020-09-07 21:24:01 -07001695 // update voltha flow to cache
1696 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1697 }
1698 } else { // No symmetric flow found
1699 if (!replicate_flow) { // No flow replication
1700 OPENOLT_LOG(INFO, openolt_log_id, "not a symmetric flow and replication is not needed\n");
1701 flow_id = get_flow_id();
1702 if (flow_id == INVALID_FLOW_ID) {
1703 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocated flow id for voltha-flow-id=%lu\n", voltha_flow_id);
1704 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1705 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001706 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001707 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001708 flow_type, alloc_id, network_intf_id, gemport_id, classifier,
Burak Gurdaga0523592021-02-24 15:17:47 +00001709 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001710 if (st.error_code() == grpc::StatusCode::OK) {
1711 device_flow dev_fl;
1712 dev_fl.is_flow_replicated = false;
1713 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // Invalid
1714 dev_fl.voltha_flow_id = voltha_flow_id;
Girish Gowdra72bb4652022-01-18 17:04:30 -08001715 dev_fl.flow_type = flow_type;
Girish Gowdra252f4972020-09-07 21:24:01 -07001716 dev_fl.params[0].flow_id = flow_id;
1717 dev_fl.params[0].gemport_id = gemport_id;
1718 dev_fl.params[0].pbit = classifier.o_pbits();
1719 // update voltha flow to cache
1720 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1721 } else {
1722 // Free the flow id on failure
1723 free_flow_id(flow_id);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001724 return st;
Girish Gowdra252f4972020-09-07 21:24:01 -07001725 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001726 } else { // Flow to be replicated
1727 OPENOLT_LOG(INFO, openolt_log_id,"not a symmetric flow and replication is needed\n");
Girish Gowdra52997cc2022-06-02 20:58:50 -07001728 if (pbit_to_gemport.size() > NUMBER_OF_PBITS) {
Girish Gowdra252f4972020-09-07 21:24:01 -07001729 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pbit-to-gemport map size=%lu", pbit_to_gemport.size())
1730 return ::Status(grpc::StatusCode::OUT_OF_RANGE, "pbit-to-gemport-map-len-invalid-for-flow-replication");
1731 }
Girish Gowdra52997cc2022-06-02 20:58:50 -07001732 uint16_t flow_ids[MAX_NUMBER_OF_REPLICATED_FLOWS];
Girish Gowdra252f4972020-09-07 21:24:01 -07001733 device_flow dev_fl;
Girish Gowdra52997cc2022-06-02 20:58:50 -07001734 if (get_flow_ids(pbit_to_gemport.size(), flow_ids)) {
Girish Gowdra252f4972020-09-07 21:24:01 -07001735 uint8_t cnt = 0;
1736 dev_fl.is_flow_replicated = true;
1737 dev_fl.voltha_flow_id = voltha_flow_id;
1738 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // invalid
Girish Gowdra52997cc2022-06-02 20:58:50 -07001739 dev_fl.total_replicated_flows = pbit_to_gemport.size();
Girish Gowdra72bb4652022-01-18 17:04:30 -08001740 dev_fl.flow_type = flow_type;
Girish Gowdra252f4972020-09-07 21:24:01 -07001741 for (google::protobuf::Map<unsigned int, unsigned int>::const_iterator it=pbit_to_gemport.begin(); it!=pbit_to_gemport.end(); it++) {
1742 dev_fl.params[cnt].flow_id = flow_ids[cnt];
1743 dev_fl.params[cnt].pbit = it->first;
1744 dev_fl.params[cnt].gemport_id = it->second;
1745
1746 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1747 flow_id = dev_fl.params[cnt].flow_id;
1748 gemport_id = dev_fl.params[cnt].gemport_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001749 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001750 cl.set_o_pbits(dev_fl.params[cnt].pbit);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001751 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001752 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001753 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001754 if (st.error_code() != grpc::StatusCode::OK) {
1755 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);
1756 // Remove any successfully replicated flows installed so far for the voltha_flow_id
1757 if (cnt > 0) {
1758 for (int8_t j = cnt-1; j >= 0; j--) {
1759 flow_id = dev_fl.params[j].flow_id;
1760 FlowRemove_(flow_id, flow_type);
1761 }
1762 }
1763 // Free up all the flow IDs on failure
Girish Gowdra52997cc2022-06-02 20:58:50 -07001764 free_flow_ids(pbit_to_gemport.size(), flow_ids);
Girish Gowdra252f4972020-09-07 21:24:01 -07001765 return st;
1766 }
1767 cnt++;
1768 }
1769 // On successful flow replication update voltha-flow-id to device-flow map to cache
1770 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1771 } else {
1772 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocate flow ids for replication voltha-flow-id=%lu\n", voltha_flow_id);
1773 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1774 }
1775 }
1776 }
1777
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001778 if (datapathFlow) {
1779 // Create the pon-gem to onu-uni mapping
1780 symmetric_datapath_flow_id_map_key key(access_intf_id, onu_id, uni_id, tech_profile_id, flow_type);
1781 bcmos_fastlock_lock(&symmetric_datapath_flow_id_lock);
1782 symmetric_datapath_flow_id_map[key] = voltha_flow_id;
1783 bcmos_fastlock_unlock(&symmetric_datapath_flow_id_lock, 0);
1784 }
1785
1786 return st;
Girish Gowdra252f4972020-09-07 21:24:01 -07001787}
1788
1789
Craig Lutgen967a1d02018-11-27 10:41:51 -06001790Status 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 +00001791 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001792 int32_t alloc_id, int32_t network_intf_id,
1793 int32_t gemport_id, const ::openolt::Classifier& classifier,
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001794 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie,
Burak Gurdaga0523592021-02-24 15:17:47 +00001795 int32_t group_id, uint32_t tech_profile_id, bool aes_enabled) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001796 bcmolt_flow_cfg cfg;
1797 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001798 int32_t o_vid = -1;
1799 bool single_tag = false;
1800 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001801 bcmolt_classifier c_val = { };
1802 bcmolt_action a_val = { };
1803 bcmolt_tm_queue_ref tm_val = { };
1804 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05001805 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001806
Jason Huang09b73ea2020-01-08 17:52:05 +08001807 OPENOLT_LOG(INFO, openolt_log_id, "flow add received for flow_id=%u, flow_type=%s\n", flow_id, flow_type.c_str());
1808
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001809 key.flow_id = flow_id;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08001810 if (flow_type == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001811 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08001812 } else if (flow_type == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001813 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08001814 } else if (flow_type == multicast) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001815 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001816 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001817 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001818 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001819 }
1820
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001821 BCMOLT_CFG_INIT(&cfg, flow, key);
1822 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001823
Jason Huang09b73ea2020-01-08 17:52:05 +08001824 if (action.cmd().trap_to_host()) {
Girish Gowdra1935e6a2020-10-31 21:48:22 -07001825 Status resp = handle_acl_rule_install(onu_id, flow_id, gemport_id, flow_type, access_intf_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001826 network_intf_id, classifier);
Jason Huang09b73ea2020-01-08 17:52:05 +08001827 return resp;
1828 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001829
1830 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1831
1832 if (access_intf_id >= 0 && network_intf_id >= 0) {
1833 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1834 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1835 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08001836 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1837 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001838 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1839 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1840 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1841 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1842 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001843 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001844 } else {
1845 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
1846 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001847 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001848
Burak Gurdaga0523592021-02-24 15:17:47 +00001849 if (onu_id >= ONU_ID_START) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001850 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
1851 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001852 if (gemport_id >= GEM_PORT_ID_START) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001853 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
1854 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001855 if (gemport_id >= GEM_PORT_ID_START && port_no != 0) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001856 bcmos_fastlock_lock(&data_lock);
1857 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
1858 port_to_flows[port_no].insert(key.flow_id);
1859 flowid_to_gemport[key.flow_id] = gemport_id;
1860 }
1861 else
1862 {
1863 flowid_to_port[key.flow_id] = port_no;
1864 }
1865 bcmos_fastlock_unlock(&data_lock, 0);
1866 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001867
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001868 if (priority_value >= 0) {
1869 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
1870 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301871
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001872 } else { // MULTICAST FLOW
1873 if (group_id >= 0) {
1874 BCMOLT_MSG_FIELD_SET(&cfg, group_id, group_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001875 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001876 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1877 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001878 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001879
1880 {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001881 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001882 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001883 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
1884 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001885 }
1886
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001887 if (classifier.dst_mac().size() > 0) {
1888 bcmos_mac_address d_mac = {};
1889 bcmos_mac_address_init(&d_mac);
1890 memcpy(d_mac.u8, classifier.dst_mac().data(), sizeof(d_mac.u8));
1891 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_mac %02x:%02x:%02x:%02x:%02x:%02x\n", d_mac.u8[0],
1892 d_mac.u8[1], d_mac.u8[2], d_mac.u8[3], d_mac.u8[4], d_mac.u8[5]);
1893 BCMOLT_FIELD_SET(&c_val, classifier, dst_mac, d_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001894 }
1895
Girish Gowdraf83e17a2022-02-16 16:27:00 -08001896 if (classifier.src_mac().size() > 0) {
1897 bcmos_mac_address s_mac = {};
1898 bcmos_mac_address_init(&s_mac);
1899 memcpy(s_mac.u8, classifier.src_mac().data(), sizeof(s_mac.u8));
1900 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_mac %02x:%02x:%02x:%02x:%02x:%02x\n", s_mac.u8[0],
1901 s_mac.u8[1], s_mac.u8[2], s_mac.u8[3], s_mac.u8[4], s_mac.u8[5]);
1902 BCMOLT_FIELD_SET(&c_val, classifier, src_mac, s_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001903 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001904
1905 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001906 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
1907 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001908 }
1909
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001910 if (classifier.dst_ip()) {
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08001911 bcmos_ipv4_address d_ip = {};
1912 bcmos_ipv4_address_init(&d_ip);
1913 d_ip.u32 = classifier.dst_ip();
1914 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_ip %04x\n", d_ip.u32);
1915 BCMOLT_FIELD_SET(&c_val, classifier, dst_ip, d_ip);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001916 }
1917
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08001918 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001919 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001920 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001921 }
1922 */
1923
1924 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001925 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
1926 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001927 }
1928
1929 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001930 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
1931 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001932 }
1933
1934 if (!classifier.pkt_tag_type().empty()) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001935 if (classifier.o_vid()) {
1936 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
1937 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
1938 }
1939
1940 if (classifier.i_vid()) {
1941 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
1942 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
1943 }
1944
1945 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
1946 if (classifier.pkt_tag_type().compare("untagged") == 0) {
1947 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
1948 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
1949 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
1950 single_tag = true;
1951
1952 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301953 // OpenOlt adapter will send 0xFF in case of no pbit classification
1954 // If it is any other value (0 to 7), it is for outer pbit classification.
1955 // OpenFlow protocol does not provide inner pbit classification (in case of double tagged packets),
1956 // and VOLTHA has not used any workaround to solve this problem (for ex: use metadata field).
1957 // Also there exists no use case for i-pbit classification, so we can safely ignore this for now.
1958 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001959 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301960 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001961 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
1962 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001963
Jason Huang09b73ea2020-01-08 17:52:05 +08001964 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301965 // Same comments as in case of "single_tag" packets.
1966 // 0xFF means no pbit classification, otherwise a valid PCP (0 to 7).
1967 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001968 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301969 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001970 }
1971 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001972 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001973 }
1974
Jason Huang09b73ea2020-01-08 17:52:05 +08001975 const ::openolt::ActionCmd& cmd = action.cmd();
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001976
Jason Huang09b73ea2020-01-08 17:52:05 +08001977 if (cmd.add_outer_tag()) {
1978 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
1979 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001980 }
1981
Jason Huang09b73ea2020-01-08 17:52:05 +08001982 if (cmd.remove_outer_tag()) {
1983 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
1984 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
1985 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301986
Girish Gowdraf83e17a2022-02-16 16:27:00 -08001987 if (cmd.translate_outer_tag()) {
1988 OPENOLT_LOG(DEBUG, openolt_log_id, "action translate o_tag\n");
1989 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_XLATE_OUTER_TAG);
1990 }
1991
Jason Huang09b73ea2020-01-08 17:52:05 +08001992 if (action.o_vid()) {
1993 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
1994 o_vid = action.o_vid();
1995 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
1996 }
1997
1998 if (action.o_pbits()) {
1999 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
2000 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
2001 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05302002
Jason Huang09b73ea2020-01-08 17:52:05 +08002003 if (action.i_vid()) {
2004 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
2005 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
2006 }
2007
2008 if (action.i_pbits()) {
2009 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
2010 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
2011 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05302012
Jason Huang09b73ea2020-01-08 17:52:05 +08002013 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
2014
Burak Gurdaga0523592021-02-24 15:17:47 +00002015 if ((access_intf_id >= 0) && (onu_id >= ONU_ID_START)) {
Jason Huang09b73ea2020-01-08 17:52:05 +08002016 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
2017 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002018 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 +00002019
Jason Huang09b73ea2020-01-08 17:52:05 +08002020 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2021 // Queue 0 on DS subscriber scheduler
2022 tm_val.queue_id = 0;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002023
Jason Huang09b73ea2020-01-08 17:52:05 +08002024 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2025 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2026 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002027
Jason Huang09b73ea2020-01-08 17:52:05 +08002028 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2029 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2030 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002031
Jason Huang09b73ea2020-01-08 17:52:05 +08002032 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2033 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
2034 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 +00002035
Jason Huang09b73ea2020-01-08 17:52:05 +08002036 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2037 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2038 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2039 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 +00002040
Jason Huang09b73ea2020-01-08 17:52:05 +08002041 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2042 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2043 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2044 }
2045 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
2046 // NNI Scheduler ID
2047 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2048 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2049 // Queue 0 on NNI scheduler
2050 tm_val.queue_id = 0;
2051 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2052 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2053 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_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, queue_id = %d, sched_id = %d, intf_type %s\n", \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002056 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2057 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2058
Jason Huang09b73ea2020-01-08 17:52:05 +08002059 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2060 /* Fetch TM QMP ID mapped to US NNI scheduler */
2061 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2062 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2063 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2064 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2065 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 +00002066
Jason Huang09b73ea2020-01-08 17:52:05 +08002067 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 +00002068 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2069 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002070 }
Shad Ansari39739bc2018-09-13 21:38:37 +00002071 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302072 } else {
2073 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2074 tm_val.queue_id = 0;
2075
2076 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2077 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2078 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2079
2080 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2081 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
2082 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00002083 }
2084
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002085 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002086
Girish Gowdra252f4972020-09-07 21:24:01 -07002087#ifndef SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002088 // BAL 3.1 supports statistics only for unicast flows.
2089 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
2090 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
2091 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002092#endif // SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002093
Girish Gowdra252f4972020-09-07 21:24:01 -07002094#ifndef SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002095#ifdef FLOW_CHECKER
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002096 //Flow Checker, To avoid duplicate flow.
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002097 if (flow_id_counters != 0) {
2098 bool b_duplicate_flow = false;
Jason Huang09b73ea2020-01-08 17:52:05 +08002099 std::map<flow_pair, int>::iterator it;
2100
2101 for(it = flow_map.begin(); it != flow_map.end(); it++) {
2102 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(it->first.first, it->first.second, ONU_ID)) && \
2103 (key.flow_type == it->first.second) && \
2104 (cfg.data.svc_port_id == get_flow_status(it->first.first, it->first.second, SVC_PORT_ID)) && \
2105 (cfg.data.priority == get_flow_status(it->first.first, it->first.second, PRIORITY)) && \
2106 (cfg.data.cookie == get_flow_status(it->first.first, it->first.second, COOKIE)) && \
2107 (cfg.data.ingress_intf.intf_type == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_TYPE)) && \
2108 (cfg.data.ingress_intf.intf_id == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_ID)) && \
2109 (cfg.data.egress_intf.intf_type == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_TYPE)) && \
2110 (cfg.data.egress_intf.intf_id == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_ID)) && \
2111 (c_val.o_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_VID)) && \
2112 (c_val.o_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_PBITS)) && \
2113 (c_val.i_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_VID)) && \
2114 (c_val.i_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_PBITS)) && \
2115 (c_val.ether_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_ETHER_TYPE)) && \
2116 (c_val.ip_proto == get_flow_status(it->first.first, it->first.second, CLASSIFIER_IP_PROTO)) && \
2117 (c_val.src_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_SRC_PORT)) && \
2118 (c_val.dst_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_DST_PORT)) && \
2119 (c_val.pkt_tag_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_PKT_TAG_TYPE)) && \
2120 (cfg.data.egress_qos.type == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TYPE)) && \
2121 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_QUEUE_ID)) && \
2122 (cfg.data.egress_qos.tm_sched.id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TM_SCHED_ID)) && \
2123 (a_val.cmds_bitmask == get_flow_status(it->first.first, it->first.second, ACTION_CMDS_BITMASK)) && \
2124 (a_val.o_vid == get_flow_status(it->first.first, it->first.second, ACTION_O_VID)) && \
2125 (a_val.i_vid == get_flow_status(it->first.first, it->first.second, ACTION_I_VID)) && \
2126 (a_val.o_pbits == get_flow_status(it->first.first, it->first.second, ACTION_O_PBITS)) && \
2127 (a_val.i_pbits == get_flow_status(it->first.first, it->first.second, ACTION_I_PBITS)) && \
2128 (cfg.data.state == get_flow_status(it->first.first, it->first.second, STATE)) && \
2129 (cfg.data.group_id == get_flow_status(it->first.first, it->first.second, GROUP_ID));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002130#ifdef SHOW_FLOW_PARAM
2131 // Flow Parameter
2132 FLOW_PARAM_LOG();
2133#endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002134 if (b_duplicate_flow) {
2135 FLOW_LOG(WARNING, "Flow duplicate", 0);
2136 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
2137 }
2138 }
2139 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002140#endif // FLOW_CHECKER
2141#endif // SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002142
2143 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2144 if (err) {
2145 FLOW_LOG(ERROR, "Flow add failed", err);
2146 return bcm_to_grpc_err(err, "flow add failed");
2147 } else {
2148 FLOW_LOG(INFO, "Flow add ok", err);
2149 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002150 flow_map[std::pair<int, int>(key.flow_id,key.flow_type)] = flow_map.size();
2151 flow_id_counters = flow_map.size();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002152 bcmos_fastlock_unlock(&data_lock, 0);
Girish Gowdra252f4972020-09-07 21:24:01 -07002153
2154 }
Burak Gurdaga0523592021-02-24 15:17:47 +00002155
2156 /*
2157 Enable AES encryption on GEM ports if they are used in downstream unicast flows.
2158 Rationale: We can't do upstream encryption in GPON. This change addresses the common denominator (and also minimum viable)
2159 use case for both technologies which is downstream unicast GEM port encryption. Since the downstream traffic is inherently
2160 broadcast to all the ONUs behind a PON port, encrypting the individual subscriber traffic in this direction is important
2161 and considered good enough in terms of security (See Section 12.1 of G.984.3). For upstream unicast and downstream multicast
2162 GEM encryption, we need to make additional changes specific to XGSPON. This will be done as a future work.
2163 */
2164 if (aes_enabled && (access_intf_id >= 0) && (gemport_id >= GEM_PORT_ID_START) && (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM)) {
2165 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 +05302166 enable_encryption_for_gem_port(access_intf_id, gemport_id, board_technology);
Burak Gurdaga0523592021-02-24 15:17:47 +00002167 } else {
2168 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);
2169 }
2170
Girish Gowdra252f4972020-09-07 21:24:01 -07002171 return Status::OK;
2172}
2173
2174Status FlowRemoveWrapper_(const ::openolt::Flow* request) {
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002175 int32_t access_intf_id = request->access_intf_id();
2176 int32_t onu_id = request->onu_id();
2177 int32_t uni_id = request->uni_id();
2178 uint32_t tech_profile_id = request->tech_profile_id();
Girish Gowdra252f4972020-09-07 21:24:01 -07002179 uint64_t voltha_flow_id = request->flow_id();
2180 Status st;
2181
2182 // If Voltha flow is not installed, return fail
2183 if (! is_voltha_flow_installed(voltha_flow_id)) {
2184 OPENOLT_LOG(ERROR, openolt_log_id, "voltha_flow_id=%lu not found\n", voltha_flow_id);
2185 return ::Status(grpc::StatusCode::NOT_FOUND, "voltha-flow-not-found");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002186 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04002187
Girish Gowdra252f4972020-09-07 21:24:01 -07002188 const device_flow *dev_fl = get_device_flow(voltha_flow_id);
2189 if (dev_fl == NULL) {
2190 OPENOLT_LOG(ERROR, openolt_log_id, "device flow for voltha_flow_id=%lu in the cache is NULL\n", voltha_flow_id);
2191 return ::Status(grpc::StatusCode::INTERNAL, "device-flow-null-in-cache");
2192 }
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002193 std::string flow_type = dev_fl->flow_type;
Girish Gowdra252f4972020-09-07 21:24:01 -07002194 if (dev_fl->is_flow_replicated) {
2195 // Note: Here we are ignoring FlowRemove failures
Girish Gowdra52997cc2022-06-02 20:58:50 -07002196 for (int i=0; i<dev_fl->total_replicated_flows; i++) {
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002197 st = FlowRemove_(dev_fl->params[i].flow_id, flow_type);
Girish Gowdra252f4972020-09-07 21:24:01 -07002198 if (st.error_code() == grpc::StatusCode::OK) {
2199 free_flow_id(dev_fl->params[i].flow_id);
2200 }
2201 }
2202 } else {
2203 // Note: Here we are ignoring FlowRemove failures
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002204 st = FlowRemove_(dev_fl->params[0].flow_id, flow_type);
Girish Gowdra252f4972020-09-07 21:24:01 -07002205 if (st.error_code() == grpc::StatusCode::OK) {
2206 free_flow_id(dev_fl->params[0].flow_id);
2207 }
2208 }
2209 // remove the flow from cache on voltha flow removal
2210 remove_voltha_flow_from_cache(voltha_flow_id);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002211
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002212 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 -07002213 // Remove onu-uni mapping for the pon-gem key
2214 bcmos_fastlock_lock(&symmetric_datapath_flow_id_lock);
2215 symmetric_datapath_flow_id_map.erase(key);
2216 bcmos_fastlock_unlock(&symmetric_datapath_flow_id_lock, 0);
2217
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002218 return Status::OK;
2219}
2220
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002221Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
2222
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002223 bcmolt_flow_cfg cfg;
2224 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002225
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002226 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002227 key.flow_id = flow_id;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002228 if (flow_type == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002229 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002230 } else if (flow_type == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002231 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002232 } else if(flow_type == multicast) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002233 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002234 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002235 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002236 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
2237 }
2238
Jason Huang09b73ea2020-01-08 17:52:05 +08002239 OPENOLT_LOG(INFO, openolt_log_id, "flow remove received for flow_id=%u, flow_type=%s\n",
2240 flow_id, flow_type.c_str());
2241
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002242 bcmos_fastlock_lock(&acl_packet_trap_handler_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002243 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
2244 int32_t gemport_id = -1;
2245 int32_t intf_id = -1;
2246 int16_t acl_id = -1;
2247 if (flow_to_acl_map.count(fl_id_fl_dir) > 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002248
2249 acl_id_intf_id ac_id_if_id = flow_to_acl_map[fl_id_fl_dir];
2250 acl_id = std::get<0>(ac_id_if_id);
2251 intf_id = std::get<1>(ac_id_if_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002252 // cleanup acl only if it is a valid acl. If not valid acl, it may be datapath flow.
2253 if (acl_id >= 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002254 Status resp = handle_acl_rule_cleanup(acl_id, intf_id, flow_type);
Jason Huang09b73ea2020-01-08 17:52:05 +08002255 if (resp.ok()) {
2256 OPENOLT_LOG(INFO, openolt_log_id, "acl removed ok for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2257 flow_to_acl_map.erase(fl_id_fl_dir);
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002258
2259 // 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
2260 if (trap_to_host_pkt_info_with_vlan_for_flow_id.count(flow_id) > 0) {
2261 trap_to_host_pkt_info_with_vlan pkt_info_with_vlan = trap_to_host_pkt_info_with_vlan_for_flow_id[flow_id];
2262 // Formulate the trap_to_host_pkt_info tuple key
2263 trap_to_host_pkt_info pkt_info(std::get<0>(pkt_info_with_vlan),
2264 std::get<1>(pkt_info_with_vlan),
2265 std::get<2>(pkt_info_with_vlan),
2266 std::get<3>(pkt_info_with_vlan));
2267 // Extract the value corresponding to trap_to_host_pkt_info key from trap_to_host_vlan_ids_for_trap_to_host_pkt_info
2268 // The value is a list of vlan_ids for the given trap_to_host_pkt_info key
2269 // Remove the vlan_id from the list that corresponded to the flow being removed.
2270 if (trap_to_host_vlan_ids_for_trap_to_host_pkt_info.count(pkt_info) > 0) {
2271 trap_to_host_vlan_ids_for_trap_to_host_pkt_info[pkt_info].remove(std::get<4>(pkt_info_with_vlan));
2272 } else {
2273 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",
2274 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));
2275 }
2276
2277 } else {
2278 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);
2279 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002280 } else {
2281 OPENOLT_LOG(ERROR, openolt_log_id, "acl remove error for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2282 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002283 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002284 return resp;
2285 }
2286 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002287 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002288
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002289 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002290 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002291 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002292 flowid_to_gemport.erase(key.flow_id);
2293 port_to_flows[port_no].erase(key.flow_id);
2294 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
2295 }
2296 else
2297 {
2298 flowid_to_port.erase(key.flow_id);
2299 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002300 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002301
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002302 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002303
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002304 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002305 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07002306 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 -04002307 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
2308 }
2309
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002310 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002311 if (flow_id_counters != 0) {
2312 std::map<flow_pair, int>::iterator it;
2313 for(it = flow_map.begin(); it != flow_map.end(); it++) {
2314 if (it->first.first == flow_id && it->first.second == key.flow_type) {
2315 flow_id_counters -= 1;
2316 flow_map.erase(it);
Shivanagouda Malaginahallie707d612023-08-22 10:40:25 +00002317 break; /* After match found break from the loop, otherwise leads to crash */
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002318 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002319 }
2320 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002321 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
2322
Jason Huang09b73ea2020-01-08 17:52:05 +08002323 flow_to_acl_map.erase(fl_id_fl_dir);
2324
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002325 bcmos_fastlock_unlock(&data_lock, 0);
2326
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002327 return Status::OK;
2328}
2329
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002330bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
2331 bcmos_errno err;
2332 bcmolt_tm_sched_cfg tm_sched_cfg;
2333 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2334 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
2335
Jason Huangbf45ffb2019-10-30 17:29:02 +08002336 //check TM scheduler has configured or not
2337 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2338 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002339 #ifdef TEST_MODE
2340 // It is impossible to mock the setting of tm_sched_cfg.data.state because
2341 // the actual bcmolt_cfg_get passes the address of tm_sched_cfg.hdr and we cannot
2342 // set the tm_sched_cfg.data.state. So a new stub function is created and address
2343 // of tm_sched_cfg is passed. This is one-of case where we need to add test specific
2344 // code in production code.
2345 err = bcmolt_cfg_get__tm_sched_stub(dev_id, &tm_sched_cfg);
2346 #else
Jason Huangbf45ffb2019-10-30 17:29:02 +08002347 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002348 #endif
Jason Huangbf45ffb2019-10-30 17:29:02 +08002349 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07002350 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 +08002351 return err;
2352 }
2353 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
2354 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
2355 return BCM_ERR_OK;
2356 }
2357
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002358 // bcmbal_tm_sched_owner
2359 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2360
2361 /**< The output of the tm_sched object instance */
2362 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
2363
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002364 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002365 // In upstream it is NNI scheduler
2366 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 -08002367 } else if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002368 // In downstream it is PON scheduler
2369 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2370 }
2371
2372 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2373
2374 // bcmbal_tm_sched_type
2375 // set the deafult policy to strict priority
2376 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2377
2378 // num_priorities: Max number of strict priority scheduling elements
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002379 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, NUM_OF_PRIORITIES);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002380
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002381 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2382 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002383 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
2384 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002385 return err;
2386 }
2387
2388 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2389 direction.c_str(), tm_sched_key.id, intf_id);
2390 return BCM_ERR_OK;
2391}
2392
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002393bcmos_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 -07002394 uint32_t alloc_id, ::tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
2395 ::tech_profile::SchedulingPolicy sched_policy, ::tech_profile::TrafficShapingInfo tf_sh_info,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002396 uint32_t tech_profile_id) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002397
2398 bcmos_errno err;
2399
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002400 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002401 bcmolt_tm_sched_cfg tm_sched_cfg;
2402 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002403 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 -04002404
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002405 // bcmbal_tm_sched_owner
2406 // In downstream it is sub_term scheduler
2407 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002408
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002409 /**< The output of the tm_sched object instance */
2410 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002411
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002412 // bcmbal_tm_sched_parent
2413 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2414 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 +00002415 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 +00002416 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 +00002417 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002418 be achieved using the' virtual' type of attachment.
2419 tm_sched_owner.u.sub_term.intf_id = intf_id;
2420 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2421 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002422
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002423 // bcmbal_tm_sched_type
2424 // set the deafult policy to strict priority
2425 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002426
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002427 // num_priorities: Max number of strict priority scheduling elements
2428 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002429
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002430 // bcmbal_tm_shaping
2431 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2432 uint32_t cir = tf_sh_info.cir();
2433 uint32_t pir = tf_sh_info.pir();
2434 uint32_t burst = tf_sh_info.pbs();
2435 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2436 cir, pir, burst);
2437 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2438 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2439 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2440 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2441 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2442 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002443 }
2444
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002445 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002446 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002447 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Girish Gowdra72cbee92021-11-05 15:16:18 -07002448intf_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, \
2449port_no, tm_sched_cfg.hdr.hdr.err_text, err);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002450 return err;
2451 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002452 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2453uni_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 -08002454
2455 } else { //upstream
Arthur Syu094df162022-04-21 17:50:06 +08002456 std::string intf_technology = intf_technologies[intf_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002457 bcmolt_itupon_alloc_cfg cfg;
2458 bcmolt_itupon_alloc_key key = { };
2459 key.pon_ni = intf_id;
2460 key.alloc_id = alloc_id;
Arthur Syu094df162022-04-21 17:50:06 +08002461 int bw_granularity = (intf_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
Burak Gurdag623fada2021-04-20 22:02:36 +00002462 /*
2463 PIR: Maximum Bandwidth
2464 CIR: Assured Bandwidth
2465 GIR: Fixed Bandwidth
2466 */
Burak Gurdag03919c72020-02-04 22:46:57 +00002467 int pir_bw = tf_sh_info.pir()*125; // conversion from kbps to bytes/sec
2468 int cir_bw = tf_sh_info.cir()*125; // conversion from kbps to bytes/sec
Burak Gurdag623fada2021-04-20 22:02:36 +00002469 int gir_bw = tf_sh_info.gir()*125; // conversion from kbps to bytes/sec
2470 int guaranteed_bw = cir_bw+gir_bw;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002471 //offset to match bandwidth granularity
2472 int offset_pir_bw = pir_bw%bw_granularity;
Burak Gurdag623fada2021-04-20 22:02:36 +00002473 int offset_gir_bw = gir_bw%bw_granularity;
2474 int offset_guaranteed_bw = guaranteed_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002475
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002476 pir_bw = pir_bw - offset_pir_bw;
Burak Gurdag623fada2021-04-20 22:02:36 +00002477 gir_bw = gir_bw - offset_gir_bw;
2478 guaranteed_bw = guaranteed_bw - offset_guaranteed_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002479
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002480 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002481
Burak Gurdag623fada2021-04-20 22:02:36 +00002482 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);
2483
2484 if (pir_bw == 0) {
2485 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be at least %d bytes/sec\n",
2486 (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2487 return BCM_ERR_PARM;
2488 } else if (pir_bw < guaranteed_bw) {
2489 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed bandwidth (%d)\n",
2490 pir_bw, guaranteed_bw);
2491 return BCM_ERR_PARM;
2492 }
2493
2494 // Setting additional bw eligibility and validating bw provisionings
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002495 switch (additional_bw) {
Burak Gurdag623fada2021-04-20 22:02:36 +00002496
2497 case tech_profile::AdditionalBW::AdditionalBW_BestEffort: //AdditionalBW_BestEffort - For T-Cont types 4 & 5
2498 if (pir_bw == guaranteed_bw) {
2499 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2500bandwidth for additional bandwidth eligibility of type Best Effort\n");
2501 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002502 }
2503 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2504 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002505
2506 case tech_profile::AdditionalBW::AdditionalBW_NA: //AdditionalBW_NA - For T-Cont types 3 & 5
2507 if (guaranteed_bw == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002508 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2509additional bandwidth eligibility of type Non-Assured (NA)\n");
2510 return BCM_ERR_PARM;
Burak Gurdag623fada2021-04-20 22:02:36 +00002511 } else if (pir_bw == guaranteed_bw) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002512 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
Burak Gurdag623fada2021-04-20 22:02:36 +00002513bandwidth for additional bandwidth eligibility of type Non-Assured\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002514 return BCM_ERR_PARM;
2515 }
2516 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2517 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002518
2519 case tech_profile::AdditionalBW::AdditionalBW_None: //AdditionalBW_None - For T-Cont types 1 & 2
2520 if (guaranteed_bw != pir_bw) {
2521 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be equal to maximum bandwidth \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002522for additional bandwidth eligibility of type None\n");
2523 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002524 }
2525 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2526 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002527
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002528 default:
Burak Gurdag623fada2021-04-20 22:02:36 +00002529 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid additional bandwidth eligibility value (%d) supplied.\n", additional_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002530 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002531 }
Burak Gurdag623fada2021-04-20 22:02:36 +00002532
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002533 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2534 in a fine granularity. */
2535 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
Burak Gurdag623fada2021-04-20 22:02:36 +00002536 /* Since we can assign minimum 64000 bytes/sec for cbr_rt_bw, we prefer assigning
2537 gir_bw to cbr_nrt_bw to allow smaller amounts.
2538 TODO: Specify CBR_RT_BW and CBR_NRT_BW separately from VOLTHA */
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002539 /* Fixed Bandwidth with no critical requirement of shaping */
Burak Gurdag623fada2021-04-20 22:02:36 +00002540 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, gir_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002541 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
Burak Gurdag623fada2021-04-20 22:02:36 +00002542 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, guaranteed_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002543 /* Maximum allocated bandwidth allowed for this alloc ID */
2544 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
Burak Gurdag623fada2021-04-20 22:02:36 +00002545
2546 if (pir_bw == gir_bw) { // T-Cont Type 1 --> set alloc type to NONE
2547 // the condition cir_bw == 0 is implicitly satistied
2548 OPENOLT_LOG(INFO, openolt_log_id, "Setting alloc type to NONE since maximum bandwidth is equal to fixed bandwidth\n");
2549 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NONE);
2550 } else { // For other T-Cont types, set alloc type to NSR. TODO: read the default from a config file.
2551 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
2552 }
2553
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002554 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002555 for skipped allocations during quiet window */
2556 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2557 /**< Allocation Profile index for CBR non-RT Bandwidth */
2558 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2559 /**< Allocation Profile index for CBR RT Bandwidth */
2560 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2561 /**< Alloc ID Weight used in case of Extended DBA mode */
2562 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2563 /**< Alloc ID Priority used in case of Extended DBA mode */
2564 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2565 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002566
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302567 bcmolt_onu_state onu_state;
2568 bool wait_for_alloc_cfg_cmplt = false;
2569 err = get_onu_state((bcmolt_interface)intf_id, (bcmolt_onu_id)onu_id, &onu_state);
2570 if (err) {
2571 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch onu status, intf_id = %d, onu_id = %d, err = %s\n",
2572 intf_id, onu_id, bcmos_strerror(err));
2573 return err;
2574 } else if (onu_state == BCMOLT_ONU_STATE_ACTIVE) {
2575 wait_for_alloc_cfg_cmplt = true;
2576 }
2577
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002578 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002579 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002580 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 -07002581port_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 -08002582 return err;
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302583 } else if (wait_for_alloc_cfg_cmplt) {
2584 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
2585 if (err) {
2586 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 +05302587port_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 +05302588 return err;
Girish Gowdra72cbee92021-11-05 15:16:18 -07002589 }
2590 } else {
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302591 OPENOLT_LOG(INFO, openolt_log_id, "onu not active, not waiting for alloc cfg complete, onu_state = %d, intf = %d, onu=%d\n",
2592 onu_state, intf_id, onu_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302593 }
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302594
Girish Gowdra96461052019-11-22 20:13:59 +05302595 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
2596port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
2597
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002598 }
2599
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002600 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002601}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002602
Girish Gowdra252f4972020-09-07 21:24:01 -07002603Status CreateTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002604 uint32_t intf_id = traffic_scheds->intf_id();
2605 uint32_t onu_id = traffic_scheds->onu_id();
2606 uint32_t uni_id = traffic_scheds->uni_id();
2607 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002608 std::string direction;
2609 unsigned int alloc_id;
Girish Gowdra252f4972020-09-07 21:24:01 -07002610 ::tech_profile::SchedulerConfig sched_config;
2611 ::tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002612 uint32_t priority;
2613 uint32_t weight;
Girish Gowdra252f4972020-09-07 21:24:01 -07002614 ::tech_profile::SchedulingPolicy sched_policy;
2615 ::tech_profile::TrafficShapingInfo traffic_shaping_info;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002616 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002617 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002618
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002619 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002620 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002621
2622 direction = GetDirection(traffic_sched.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002623 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002624 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002625 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002626
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002627 alloc_id = traffic_sched.alloc_id();
2628 sched_config = traffic_sched.scheduler();
2629 additional_bw = sched_config.additional_bw();
2630 priority = sched_config.priority();
2631 weight = sched_config.weight();
2632 sched_policy = sched_config.sched_policy();
2633 traffic_shaping_info = traffic_sched.traffic_shaping_info();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002634 tech_profile_id = traffic_sched.tech_profile_id();
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002635 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002636 sched_policy, traffic_shaping_info, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002637 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002638 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002639 return bcm_to_grpc_err(err, "Failed to create scheduler");
2640 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002641 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002642 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002643}
Jonathan Davis70c21812018-07-19 15:32:10 -04002644
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002645bcmos_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 -04002646
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002647 bcmos_errno err;
Girish Gowdra72cbee92021-11-05 15:16:18 -07002648 bcmolt_onu_state onu_state;
Girish Gowdra96461052019-11-22 20:13:59 +05302649 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002650
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002651 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002652 bcmolt_itupon_alloc_cfg cfg;
2653 bcmolt_itupon_alloc_key key = { };
2654 key.pon_ni = intf_id;
2655 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302656 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002657
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302658 bcmolt_onu_state onu_state;
2659 bool wait_for_alloc_cfg_cmplt = false;
2660 err = get_onu_state((bcmolt_interface)intf_id, (bcmolt_onu_id)onu_id, &onu_state);
2661 if (err) {
2662 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch onu status, intf_id = %d, onu_id = %d, err = %s\n",
2663 intf_id, onu_id, bcmos_strerror(err));
2664 return err;
2665 } else if (onu_state == BCMOLT_ONU_STATE_ACTIVE) {
2666 wait_for_alloc_cfg_cmplt = true;
2667 }
2668
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002669 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002670 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2671 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07002672 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s (%d)\n",
2673 direction.c_str(), intf_id, alloc_id, cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002674 return err;
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302675 } else if (wait_for_alloc_cfg_cmplt) {
2676 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2677 if (err) {
2678 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2679pon_intf %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,intf_id,alloc_id, bcmos_strerror(err));
2680 return err;
2681 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302682 } else {
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302683 OPENOLT_LOG(INFO, openolt_log_id, "onu not active, not waiting for alloc cfg complete, onu_state = %d, intf = %d, onu=%d\n",
2684 onu_state, intf_id, onu_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302685 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002686 } else if (direction == downstream) {
2687 bcmolt_tm_sched_cfg cfg;
2688 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002689
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002690 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2691 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302692 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002693 } else {
2694 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2695 return BCM_ERR_OK;
2696 }
Girish Gowdra96461052019-11-22 20:13:59 +05302697
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002698 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2699 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2700 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002701 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
Girish Gowdra72cbee92021-11-05 15:16:18 -07002702intf_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 +00002703 return err;
2704 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002705 }
2706
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002707 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d, tech_profile_id %d\n",
2708 direction.c_str(), sched_id, intf_id, onu_id, tech_profile_id);
2709 free_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002710 return BCM_ERR_OK;
2711}
2712
Girish Gowdra252f4972020-09-07 21:24:01 -07002713Status RemoveTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002714 uint32_t intf_id = traffic_scheds->intf_id();
2715 uint32_t onu_id = traffic_scheds->onu_id();
2716 uint32_t uni_id = traffic_scheds->uni_id();
2717 std::string direction;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002718 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002719 bcmos_errno err;
2720
2721 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002722 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002723
2724 direction = GetDirection(traffic_sched.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002725 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002726 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002727 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002728
2729 int alloc_id = traffic_sched.alloc_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002730 int tech_profile_id = traffic_sched.tech_profile_id();
2731 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002732 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002733 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002734 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2735 }
2736 }
2737 return Status::OK;
2738}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002739
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002740bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2741 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002742 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002743 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2744 bcmolt_tm_qmp_key tm_qmp_key;
2745 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002746
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002747 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2748 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002749 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed tm queue mapping profile count is 16.\n");
2750 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002751 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002752
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002753 tm_qmp_key.id = tm_qmp_id;
2754 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2755 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2756 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002757
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002758 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2759 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2760 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002761 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2762 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002763
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002764 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002765 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002766 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2767 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002768 return err;
2769 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002770
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002771 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2772 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002773 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002774}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002775
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002776bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2777 bcmos_errno err;
2778 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2779 bcmolt_tm_qmp_key tm_qmp_key;
2780 tm_qmp_key.id = tm_qmp_id;
2781
2782 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2783 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2784 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002785 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2786 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002787 return err;
2788 }
2789
2790 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2791 tm_qmp_key.id);
2792 return BCM_ERR_OK;
2793}
2794
2795bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2796 bcmos_errno err;
2797
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002798 /* Create default queues on the given PON/NNI scheduler */
2799 for (int queue_id = 0; queue_id < NUMBER_OF_DEFAULT_INTERFACE_QUEUES; queue_id++) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002800 bcmolt_tm_queue_cfg tm_queue_cfg;
2801 bcmolt_tm_queue_key tm_queue_key = {};
2802 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2803 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002804 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2805 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2806 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002807
2808 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2809 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2810 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2811
2812 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2813 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002814 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", \
2815 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 +00002816 return err;
2817 }
2818
2819 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2820 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2821 }
2822 return BCM_ERR_OK;
2823}
2824
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002825bcmos_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 +00002826 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 +00002827 bcmos_errno err;
2828 bcmolt_tm_queue_cfg cfg;
2829 bcmolt_tm_queue_key key = { };
2830 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 +00002831gemport_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 +00002832
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002833 key.sched_id = (direction == upstream) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002834 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002835
2836 if (priority > 7) {
2837 return BCM_ERR_RANGE;
2838 }
2839
2840 /* FIXME: The upstream queues have to be created once only.
2841 The upstream queues on the NNI scheduler are shared by all subscribers.
2842 When the first scheduler comes in, the queues get created, and are re-used by all others.
2843 Also, these queues should be present until the last subscriber exits the system.
2844 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2845
2846 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2847 for each GEM in TECH PROFILE */
2848 key.id = queue_id_list[priority];
2849
2850 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2851 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2852 key.id = 0;
2853 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2854 }
2855 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2856 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2857 }
2858 else {
2859 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2860 }
2861
2862 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2863
2864 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2865 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
Girish Gowdra5287fde2021-07-31 00:41:45 +00002866 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002867
2868 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2869 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002870 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
Girish Gowdra72cbee92021-11-05 15:16:18 -07002871sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, tech_profile_id %d, err = %s (%d)\n", \
2872 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 +00002873 return err;
2874 }
2875
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302876 if (direction == upstream || direction == downstream) {
Thiyagarajan Subramani19168f52021-05-25 23:26:41 +05302877 Status st = install_gem_port(access_intf_id, onu_id, uni_id, gemport_id, board_technology);
Girish Gowdra252f4972020-09-07 21:24:01 -07002878 if (st.error_code() != grpc::StatusCode::ALREADY_EXISTS && st.error_code() != grpc::StatusCode::OK) {
2879 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);
2880 return BCM_ERR_INTERNAL;
2881 }
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002882 if (direction == upstream) {
2883 // Create the pon-gem to onu-uni mapping
2884 pon_gem pg(access_intf_id, gemport_id);
2885 onu_uni ou(onu_id, uni_id);
2886 bcmos_fastlock_lock(&pon_gem_to_onu_uni_map_lock);
2887 pon_gem_to_onu_uni_map[pg] = ou;
2888 bcmos_fastlock_unlock(&pon_gem_to_onu_uni_map_lock, 0);
2889 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002890 }
2891
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002892 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 +00002893intf_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 +00002894 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002895}
2896
Girish Gowdra252f4972020-09-07 21:24:01 -07002897Status CreateTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002898 uint32_t intf_id = traffic_queues->intf_id();
2899 uint32_t onu_id = traffic_queues->onu_id();
2900 uint32_t uni_id = traffic_queues->uni_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002901 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002902 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002903 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002904 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002905 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 +00002906
2907 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2908 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2909 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2910 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002911 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002912
2913 direction = GetDirection(traffic_queue.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002914 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002915 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002916 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002917
2918 queues_priority_q[i] = traffic_queue.priority();
2919 queues_pbit_map[i] = traffic_queue.pbit_map();
2920 }
2921
2922 std::vector<uint32_t> tmq_map_profile(8, 0);
2923 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2924 queues_priority_q, COUNT_OF(queues_priority_q));
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002925 sched_id = (direction == upstream) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002926 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002927
2928 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2929 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002930 err = CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2931 if (err != BCM_ERR_OK) {
2932 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2933 return bcm_to_grpc_err(err, "Failed to create tm queue mapping profile");
2934 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002935 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2936 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2937 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2938 }
2939 }
2940
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002941 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002942 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002943
2944 direction = GetDirection(traffic_queue.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002945 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002946 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002947 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002948
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002949 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 +00002950
Girish Gowdruf26cf882019-05-01 23:47:58 -07002951 // If the queue exists already, lets not return failure and break the loop.
2952 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002953 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002954 return bcm_to_grpc_err(err, "Failed to create queue");
2955 }
2956 }
2957 return Status::OK;
2958}
2959
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002960bcmos_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 +00002961 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 +00002962 bcmolt_tm_queue_cfg cfg;
2963 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002964 bcmos_errno err;
2965
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302966 // Gemports are bi-directional (except in multicast case). We create the gem port when we create the
2967 // upstream/downstream queue (see CreateQueue function) and it makes sense to delete them when remove the queues.
2968 // For multicast case we do not manage the install/remove of gem port in agent application. It is managed by BAL.
2969 if (direction == upstream || direction == downstream) {
Thiyagarajan Subramani19168f52021-05-25 23:26:41 +05302970 Status st = remove_gem_port(access_intf_id, onu_id, uni_id, gemport_id, board_technology);
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302971 if (st.error_code() != grpc::StatusCode::OK) {
2972 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 -07002973 // We should further cleanup proceed, do not return error yet..
2974 // return BCM_ERR_INTERNAL;
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302975 }
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002976 if (direction == upstream) {
2977 // Remove the pon-gem to onu-uni mapping
2978 pon_gem pg(access_intf_id, gemport_id);
2979 bcmos_fastlock_lock(&pon_gem_to_onu_uni_map_lock);
2980 pon_gem_to_onu_uni_map.erase(pg);
2981 bcmos_fastlock_unlock(&pon_gem_to_onu_uni_map_lock, 0);
2982 }
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302983 }
2984
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002985 if (direction == downstream) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002986 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2987 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 +00002988 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002989 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002990 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 -08002991 return BCM_ERR_OK;
2992 }
2993 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002994 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2995 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002996 return BCM_ERR_OK;
2997 }
2998
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002999 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
3000 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
3001 // Reset the queue id to 0 when using fixed queue.
3002 key.id = 0;
3003 }
3004 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
3005 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
3006 }
3007 else {
3008 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
3009 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003010
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003011 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
3012 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003013 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003014 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 -07003015tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s (%d)\n",
3016 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 -08003017 return err;
3018 }
3019
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003020 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
3021intf_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 -08003022
3023 return BCM_ERR_OK;
3024}
3025
Girish Gowdra252f4972020-09-07 21:24:01 -07003026Status RemoveTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003027 uint32_t intf_id = traffic_queues->intf_id();
3028 uint32_t onu_id = traffic_queues->onu_id();
3029 uint32_t uni_id = traffic_queues->uni_id();
3030 uint32_t port_no = traffic_queues->port_no();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00003031 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003032 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003033 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003034 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003035 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 -07003036 Status ret_code = Status::OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003037
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003038 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07003039 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003040
3041 direction = GetDirection(traffic_queue.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08003042 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003043 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08003044 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003045
Burak Gurdag2f2618c2020-04-23 13:20:30 +00003046 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 -08003047 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003048 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdra72cbee92021-11-05 15:16:18 -07003049 ret_code = bcm_to_grpc_err(err, "Failed to remove one or more queues");
3050 // Do not return here. We should continue to remove the remaining queues and its associated gem ports
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003051 }
Jonathan Davis70c21812018-07-19 15:32:10 -04003052 }
3053
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08003054 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE && (direction == upstream || \
3055 direction == downstream && is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id))) {
3056 sched_id = (direction == upstream) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00003057 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003058
3059 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
3060 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05003061 err = RemoveTrafficQueueMappingProfile(tm_qmp_id);
3062 if (err != BCM_ERR_OK) {
3063 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, err = %s\n", bcmos_strerror(err));
3064 return bcm_to_grpc_err(err, "Failed to remove tm queue mapping profile");
3065 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003066 }
3067 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003068 clear_qos_type(intf_id, onu_id, uni_id);
Girish Gowdra72cbee92021-11-05 15:16:18 -07003069 return ret_code;
Jonathan Davis70c21812018-07-19 15:32:10 -04003070}
Jason Huangbf45ffb2019-10-30 17:29:02 +08003071
Girish Gowdra252f4972020-09-07 21:24:01 -07003072Status PerformGroupOperation_(const ::openolt::Group *group_cfg) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003073
3074 bcmos_errno err;
3075 bcmolt_group_key key = {};
3076 bcmolt_group_cfg grp_cfg_obj;
3077 bcmolt_group_members_update grp_mem_upd;
3078 bcmolt_members_update_command grp_mem_upd_cmd;
3079 bcmolt_group_member_info member_info = {};
3080 bcmolt_group_member_info_list_u8 members = {};
3081 bcmolt_intf_ref interface_ref = {};
3082 bcmolt_egress_qos egress_qos = {};
3083 bcmolt_tm_sched_ref tm_sched_ref = {};
3084 bcmolt_action a_val = {};
3085
3086 uint32_t group_id = group_cfg->group_id();
3087
3088 OPENOLT_LOG(INFO, openolt_log_id, "PerformGroupOperation request received for Group %d\n", group_id);
3089
3090 if (group_id >= 0) {
3091 key.id = group_id;
3092 }
3093 else {
3094 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
3095 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
3096 }
3097
3098 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3099 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
3100
3101 OPENOLT_LOG(INFO, openolt_log_id, "Checking if Group %d exists...\n",group_id);
3102
3103 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
3104 if (err != BCM_ERR_OK) {
3105 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
3106 return bcm_to_grpc_err(err, "Error in querying group");
3107 }
3108
3109 members.len = group_cfg->members_size();
3110
3111 // IMPORTANT: A member cannot be added to a group if the group type is not determined.
3112 // Group type is determined after a flow is assigned to it.
3113 // Therefore, a group must be created first, then a flow (with multicast type) must be assigned to it.
3114 // Only then we can add members to the group.
3115
3116 // if group does not exist, create it and return.
3117 if (grp_cfg_obj.data.state == BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
3118
3119 if (members.len != 0) {
3120 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);
3121 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Non-empty member list given for non-existent group");
3122 } else {
3123
3124 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3125 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, cookie, key.id);
3126
3127 /* Setting group actions and action parameters, if any.
3128 Only remove_outer_tag and translate_inner_tag actions and i_vid action parameter
3129 are supported for multicast groups in BAL 3.1.
3130 */
3131 const ::openolt::Action& action = group_cfg->action();
3132 const ::openolt::ActionCmd &cmd = action.cmd();
3133
3134 bcmolt_action_cmd_id cmd_bmask = BCMOLT_ACTION_CMD_ID_NONE;
3135 if (cmd.remove_outer_tag()) {
3136 OPENOLT_LOG(INFO, openolt_log_id, "Action remove_outer_tag applied to Group %d.\n", group_id);
3137 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
3138 }
3139
3140 if (cmd.translate_inner_tag()) {
3141 OPENOLT_LOG(INFO, openolt_log_id, "Action translate_inner_tag applied to Group %d.\n", group_id);
3142 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG);
3143 }
3144
3145 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, cmd_bmask);
3146
3147 if (action.i_vid()) {
3148 OPENOLT_LOG(INFO, openolt_log_id, "Setting action parameter i_vid=%d for Group %d.\n", action.i_vid(), group_id);
3149 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
3150 }
3151
3152 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, action, a_val);
3153
3154 // Create group
3155 err = bcmolt_cfg_set(dev_id, &(grp_cfg_obj.hdr));
3156
3157 if (BCM_ERR_OK != err) {
3158 BCM_LOG(ERROR, openolt_log_id, "Failed to create Group %d, err = %s (%d)\n", key.id, bcmos_strerror(err), err);
3159 return bcm_to_grpc_err(err, "Error in creating group");
3160 }
3161
3162 BCM_LOG(INFO, openolt_log_id, "Group %d has been created and configured with empty member list.\n", key.id);
3163 return Status::OK;
3164 }
3165 }
3166
3167 // The group already exists. Continue configuring it according to the update member command.
3168
3169 OPENOLT_LOG(INFO, openolt_log_id, "Configuring existing Group %d.\n",group_id);
3170
3171 // MEMBER LIST CONSTRUCTION
3172 // Note that members.len can be 0 here. if the group already exists and the command is SET then sending
3173 // empty list to the group is a legit operation and this actually empties the member list.
3174 members.arr = (bcmolt_group_member_info*)bcmos_calloc((members.len)*sizeof(bcmolt_group_member_info));
3175
3176 if (!members.arr) {
3177 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to allocate memory for group member list.\n");
3178 return grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "Memory exhausted during member list creation");
3179 }
3180
3181 /* SET GROUP MEMBERS UPDATE COMMAND */
Girish Gowdra252f4972020-09-07 21:24:01 -07003182 ::openolt::Group::GroupMembersCommand command = group_cfg->command();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003183 switch(command) {
Girish Gowdra252f4972020-09-07 21:24:01 -07003184 case ::openolt::Group::SET_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003185 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_SET;
3186 OPENOLT_LOG(INFO, openolt_log_id, "Setting %d members for Group %d.\n", members.len, group_id);
3187 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003188 case ::openolt::Group::ADD_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003189 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_ADD;
3190 OPENOLT_LOG(INFO, openolt_log_id, "Adding %d members to Group %d.\n", members.len, group_id);
3191 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003192 case ::openolt::Group::REMOVE_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003193 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_REMOVE;
3194 OPENOLT_LOG(INFO, openolt_log_id, "Removing %d members from Group %d.\n", members.len, group_id);
3195 break;
3196 default :
3197 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid value %d for group member command.\n", command);
3198 bcmos_free(members.arr);
3199 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group member command");
3200 }
3201
3202 // SET MEMBERS LIST
3203 for (int i = 0; i < members.len; i++) {
3204
Girish Gowdra252f4972020-09-07 21:24:01 -07003205 if (command == ::openolt::Group::REMOVE_MEMBERS) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003206 OPENOLT_LOG(INFO, openolt_log_id, "Removing group member %d from group %d\n",i,key.id);
3207 } else {
3208 OPENOLT_LOG(INFO, openolt_log_id, "Adding group member %d to group %d\n",i,key.id);
3209 }
3210
Girish Gowdra252f4972020-09-07 21:24:01 -07003211 ::openolt::GroupMember *member = (::openolt::GroupMember *) &group_cfg->members()[i];
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003212
3213 // Set member interface type
Girish Gowdra252f4972020-09-07 21:24:01 -07003214 ::openolt::GroupMember::InterfaceType if_type = member->interface_type();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003215 switch(if_type){
Girish Gowdra252f4972020-09-07 21:24:01 -07003216 case ::openolt::GroupMember::PON :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003217 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_PON);
3218 OPENOLT_LOG(INFO, openolt_log_id, "Interface type PON is assigned to GroupMember %d\n",i);
3219 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003220 case ::openolt::GroupMember::EPON_1G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003221 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_1_G);
3222 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_1G is assigned to GroupMember %d\n",i);
3223 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003224 case ::openolt::GroupMember::EPON_10G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003225 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_10_G);
3226 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_10G is assigned to GroupMember %d\n",i);
3227 break;
3228 default :
3229 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid interface type value %d for GroupMember %d.\n",if_type,i);
3230 bcmos_free(members.arr);
3231 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface type for a group member");
3232 }
3233
3234 // Set member interface id
3235 if (member->interface_id() >= 0) {
3236 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_id, member->interface_id());
3237 OPENOLT_LOG(INFO, openolt_log_id, "Interface %d is assigned to GroupMember %d\n", member->interface_id(), i);
3238 } else {
3239 bcmos_free(members.arr);
3240 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface id for a group member");
3241 }
3242
3243 // Set member interface_ref
3244 BCMOLT_FIELD_SET(&member_info, group_member_info, intf, interface_ref);
3245
3246 // Set member gem_port_id. This must be a multicast gemport.
3247 if (member->gem_port_id() >= 0) {
3248 BCMOLT_FIELD_SET(&member_info, group_member_info, svc_port_id, member->gem_port_id());
3249 OPENOLT_LOG(INFO, openolt_log_id, "GEM Port %d is assigned to GroupMember %d\n", member->gem_port_id(), i);
3250 } else {
3251 bcmos_free(members.arr);
3252 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid gem port id for a group member");
3253 }
3254
3255 // Set member scheduler id and queue_id
3256 uint32_t tm_sched_id = get_default_tm_sched_id(member->interface_id(), downstream);
3257 OPENOLT_LOG(INFO, openolt_log_id, "Scheduler %d is assigned to GroupMember %d\n", tm_sched_id, i);
3258 BCMOLT_FIELD_SET(&tm_sched_ref, tm_sched_ref, id, tm_sched_id);
3259 BCMOLT_FIELD_SET(&egress_qos, egress_qos, tm_sched, tm_sched_ref);
3260
3261 // We assume that all multicast traffic destined to a PON port is using the same fixed queue.
3262 uint32_t tm_queue_id;
3263 if (member->priority() >= 0 && member->priority() < NUMBER_OF_DEFAULT_INTERFACE_QUEUES) {
3264 tm_queue_id = queue_id_list[member->priority()];
3265 OPENOLT_LOG(INFO, openolt_log_id, "Queue %d is assigned to GroupMember %d\n", tm_queue_id, i);
3266 BCMOLT_FIELD_SET(&egress_qos, egress_qos, type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
3267 BCMOLT_FIELD_SET(&egress_qos.u.fixed_queue, egress_qos_fixed_queue, queue_id, tm_queue_id);
3268 } else {
3269 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid fixed queue priority/ID %d for GroupMember %d\n", member->priority(), i);
3270 bcmos_free(members.arr);
3271 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid queue priority for a group member");
3272 }
3273
3274 BCMOLT_FIELD_SET(&member_info, group_member_info, egress_qos, egress_qos);
3275 BCMOLT_ARRAY_ELEM_SET(&(members), i, member_info);
3276 }
3277
3278 BCMOLT_OPER_INIT(&grp_mem_upd, group, members_update, key);
3279 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.members, members);
3280 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.command, grp_mem_upd_cmd);
3281
3282 err = bcmolt_oper_submit(dev_id, &(grp_mem_upd.hdr));
3283 bcmos_free(members.arr);
3284
3285 if (BCM_ERR_OK != err) {
3286 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);
3287 return bcm_to_grpc_err(err, "Failed to submit members update operation for the group");
3288 }
3289
3290 OPENOLT_LOG(INFO, openolt_log_id, "Successfully submitted members update operation for Group %d\n", key.id);
3291
3292 return Status::OK;
3293}
Burak Gurdageb4ca2e2020-06-15 07:48:26 +00003294
3295Status DeleteGroup_(uint32_t group_id) {
3296
3297 bcmos_errno err = BCM_ERR_OK;
3298 bcmolt_group_cfg grp_cfg_obj;
3299 bcmolt_group_key key = {};
3300
3301
3302 OPENOLT_LOG(INFO, openolt_log_id, "Delete request received for group %d\n", group_id);
3303
3304 if (group_id >= 0) {
3305 key.id = group_id;
3306 } else {
3307 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
3308 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
3309 }
3310
3311 /* init the BAL INIT API */
3312 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3313
3314 OPENOLT_LOG(DEBUG, openolt_log_id, "Checking if group %d exists...\n",group_id);
3315
3316 // CONFIGURE GROUP MEMBERS
3317 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
3318 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
3319
3320 if (err != BCM_ERR_OK) {
3321 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
3322 return bcm_to_grpc_err(err, "Error in querying group");
3323 }
3324
3325 if (grp_cfg_obj.data.state != BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
3326 OPENOLT_LOG(DEBUG, openolt_log_id, "Group %d exists. Will be deleted.\n",group_id);
3327 err = bcmolt_cfg_clear(dev_id, &(grp_cfg_obj.hdr));
3328 if (err != BCM_ERR_OK) {
3329 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d cannot be deleted err = %s (%d).\n", group_id, bcmos_strerror(err), err);
3330 return bcm_to_grpc_err(err, "Failed to delete group");;
3331 }
3332 } else {
3333 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d does not exist.\n", group_id);
3334 return Status(grpc::StatusCode::NOT_FOUND, "Group not found");
3335 }
3336
3337 OPENOLT_LOG(INFO, openolt_log_id, "Group %d has been deleted successfully.\n", group_id);
3338 return Status::OK;
Jason Huang1d9cfce2020-05-20 22:58:47 +08003339}
3340
Girish Gowdra252f4972020-09-07 21:24:01 -07003341Status GetLogicalOnuDistanceZero_(uint32_t intf_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003342 bcmos_errno err = BCM_ERR_OK;
3343 uint32_t mld = 0;
3344 double LD0;
3345
3346 err = getOnuMaxLogicalDistance(intf_id, &mld);
3347 if (err != BCM_ERR_OK) {
3348 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3349 }
3350
3351 LD0 = LOGICAL_DISTANCE(mld*1000, MINIMUM_ONU_RESPONSE_RANGING_TIME, ONU_BIT_TRANSMISSION_DELAY);
3352 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance zero is %f, (PON %d)\n", LD0, intf_id);
3353 response->set_intf_id(intf_id);
3354 response->set_logical_onu_distance_zero(LD0);
3355
3356 return Status::OK;
3357}
3358
Girish Gowdra252f4972020-09-07 21:24:01 -07003359Status GetLogicalOnuDistance_(uint32_t intf_id, uint32_t onu_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003360 bcmos_errno err = BCM_ERR_OK;
3361 bcmolt_itu_onu_params itu = {};
3362 bcmolt_onu_cfg onu_cfg;
3363 bcmolt_onu_key onu_key = {};
3364 uint32_t mld = 0;
3365 double LDi;
3366
3367 onu_key.pon_ni = intf_id;
3368 onu_key.onu_id = onu_id;
3369
3370 err = getOnuMaxLogicalDistance(intf_id, &mld);
3371 if (err != BCM_ERR_OK) {
3372 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3373 }
3374
3375 /* Initialize the API struct. */
3376 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
3377 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
3378 BCMOLT_FIELD_SET_PRESENT(&itu, itu_onu_params, ranging_time);
3379 BCMOLT_FIELD_SET(&onu_cfg.data, onu_cfg_data, itu, itu);
3380 #ifdef TEST_MODE
3381 // It is impossible to mock the setting of onu_cfg.data.onu_state because
3382 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
3383 // set the onu_cfg.data.onu_state. So a new stub function is created and address
3384 // of onu_cfg is passed. This is one-of case where we need to add test specific
3385 // code in production code.
3386 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
3387 #else
3388 /* Call API function. */
3389 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
3390 #endif
3391 if (err != BCM_ERR_OK) {
3392 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);
3393 return bcm_to_grpc_err(err, "Failed to retrieve ONU ranging time");
3394 }
3395
3396 if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_ACTIVE) {
3397 OPENOLT_LOG(ERROR, openolt_log_id, "ONU is not yet activated (PON %d, ONU id %d)\n", intf_id, onu_id);
3398 return bcm_to_grpc_err(BCM_ERR_PARM, "ONU is not yet activated\n");
3399 }
3400
3401 LDi = LOGICAL_DISTANCE(mld*1000, onu_cfg.data.itu.ranging_time, ONU_BIT_TRANSMISSION_DELAY);
3402 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance is %f, (PON %d, ONU id %d)\n", LDi, intf_id, onu_id);
3403 response->set_intf_id(intf_id);
3404 response->set_onu_id(onu_id);
3405 response->set_logical_onu_distance(LDi);
3406
3407 return Status::OK;
3408}
Burak Gurdag74e3ab82020-12-17 13:35:06 +00003409
3410Status GetOnuStatistics_(uint32_t intf_id, uint32_t onu_id, openolt::OnuStatistics* onu_stats) {
3411 bcmos_errno err;
3412
3413 err = get_onu_statistics((bcmolt_interface_id)intf_id, (bcmolt_onu_id)onu_id, onu_stats);
3414
3415 if (err != BCM_ERR_OK) {
3416 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));
3417 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of ONU statistics failed");
3418 }
3419
3420 OPENOLT_LOG(INFO, openolt_log_id, "retrieved ONU statistics for PON ID = %d, ONU ID = %d\n", (int)intf_id, (int)onu_id);
3421 return Status::OK;
3422}
3423
3424Status GetGemPortStatistics_(uint32_t intf_id, uint32_t gemport_id, openolt::GemPortStatistics* gemport_stats) {
3425 bcmos_errno err;
3426
3427 err = get_gemport_statistics((bcmolt_interface_id)intf_id, (bcmolt_gem_port_id)gemport_id, gemport_stats);
3428
3429 if (err != BCM_ERR_OK) {
3430 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));
3431 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of GEMPORT statistics failed");
3432 }
3433
3434 OPENOLT_LOG(INFO, openolt_log_id, "retrieved GEMPORT statistics for PON ID = %d, GEMPORT ID = %d\n", (int)intf_id, (int)gemport_id);
3435 return Status::OK;
3436}
Orhan Kupusogluec57af02021-05-12 12:38:17 +00003437
3438Status GetPonRxPower_(uint32_t intf_id, uint32_t onu_id, openolt::PonRxPowerData* response) {
3439 bcmos_errno err = BCM_ERR_OK;
3440
3441 // check the PON intf id
3442 if (intf_id >= MAX_SUPPORTED_PON) {
3443 err = BCM_ERR_PARM;
3444 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pon intf_id - intf_id: %d, onu_id: %d\n",
3445 intf_id, onu_id);
3446 return bcm_to_grpc_err(err, "invalid pon intf_id");
3447 }
3448
3449 bcmolt_onu_rssi_measurement onu_oper; /* declare main API struct */
3450 bcmolt_onu_key onu_key; /**< Object key. */
3451 onu_rssi_compltd_key key(intf_id, onu_id);
3452 Queue<onu_rssi_complete_result> queue;
3453
3454 OPENOLT_LOG(INFO, openolt_log_id, "GetPonRxPower - intf_id %d, onu_id %d\n", intf_id, onu_id);
3455
3456 onu_key.onu_id = onu_id;
3457 onu_key.pon_ni = intf_id;
3458 /* Initialize the API struct. */
3459 BCMOLT_OPER_INIT(&onu_oper, onu, rssi_measurement, onu_key);
3460 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
3461 if (err == BCM_ERR_OK) {
3462 // initialize map
3463 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3464 onu_rssi_compltd_map.insert({key, &queue});
3465 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3466 } else {
3467 OPENOLT_LOG(ERROR, openolt_log_id, "failed to measure rssi rx power - intf_id: %d, onu_id: %d, err = %s (%d): %s\n",
3468 intf_id, onu_id, bcmos_strerror(err), err, onu_oper.hdr.hdr.err_text);
3469 return bcm_to_grpc_err(err, "failed to measure rssi rx power");
3470 }
3471
3472 onu_rssi_complete_result completed{};
3473 if (!queue.pop(completed, ONU_RSSI_COMPLETE_WAIT_TIMEOUT)) {
3474 // invalidate the queue pointer
3475 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3476 onu_rssi_compltd_map[key] = NULL;
3477 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3478 err = BCM_ERR_TIMEOUT;
3479 OPENOLT_LOG(ERROR, openolt_log_id, "timeout waiting for RSSI Measurement Completed indication intf_id %d, onu_id %d\n",
3480 intf_id, onu_id);
3481 } else {
3482 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",
3483 completed.pon_intf_id, completed.onu_id, completed.status.c_str(), completed.reason, completed.rx_power_mean_dbm);
3484
3485 response->set_intf_id(completed.pon_intf_id);
3486 response->set_onu_id(completed.onu_id);
3487 response->set_status(completed.status);
3488 response->set_fail_reason(static_cast<::openolt::PonRxPowerData_RssiMeasurementFailReason>(completed.reason));
3489 response->set_rx_power_mean_dbm(completed.rx_power_mean_dbm);
3490 }
3491
3492 // Remove entry from map
3493 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3494 onu_rssi_compltd_map.erase(key);
3495 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3496
3497 if (err == BCM_ERR_OK) {
3498 return Status::OK;
3499 } else {
3500 return bcm_to_grpc_err(err, "timeout waiting for pon rssi measurement complete indication");
3501 }
3502}
nikesh.krishnan331d38c2023-04-06 03:24:53 +05303503
3504Status GetOnuInfo_(uint32_t intf_id, uint32_t onu_id, openolt::OnuInfo *response)
3505{
3506 bcmos_errno err = BCM_ERR_OK;
3507
3508 bcmolt_onu_state onu_state;
3509
3510 bcmolt_status losi;
3511 bcmolt_status lofi;
3512 bcmolt_status loami;
3513 err = get_gpon_onu_info((bcmolt_interface)intf_id, onu_id, &onu_state, &losi, &lofi, &loami);
3514
3515 if (err == BCM_ERR_OK)
3516 {
3517
3518 response->set_onu_id(onu_id);
3519 OPENOLT_LOG(DEBUG, openolt_log_id, "onu state %d\n", onu_state);
3520 OPENOLT_LOG(DEBUG, openolt_log_id, "losi %d\n", losi);
3521 OPENOLT_LOG(DEBUG, openolt_log_id, "lofi %d\n", lofi);
3522 OPENOLT_LOG(DEBUG, openolt_log_id, "loami %d\n", loami);
3523
3524 switch (onu_state)
3525 {
3526 case bcmolt_onu_state::BCMOLT_ONU_STATE_ACTIVE:
3527 response->set_state(openolt::OnuInfo_OnuState::OnuInfo_OnuState_ACTIVE);
3528 break;
3529 case bcmolt_onu_state::BCMOLT_ONU_STATE_INACTIVE:
3530 response->set_state(openolt::OnuInfo_OnuState::OnuInfo_OnuState_INACTIVE);
3531 break;
3532 case bcmolt_onu_state::BCMOLT_ONU_STATE_UNAWARE:
3533 response->set_state(openolt::OnuInfo_OnuState::OnuInfo_OnuState_UNKNOWN);
3534 break;
3535 case bcmolt_onu_state::BCMOLT_ONU_STATE_NOT_CONFIGURED:
3536 response->set_state(openolt::OnuInfo_OnuState::OnuInfo_OnuState_NOT_CONFIGURED);
3537 break;
3538 case bcmolt_onu_state::BCMOLT_ONU_STATE_DISABLED:
3539 response->set_state(openolt::OnuInfo_OnuState::OnuInfo_OnuState_DISABLED);
3540 break;
3541 }
3542 switch (losi)
3543 {
3544 case bcmolt_status::BCMOLT_STATUS_ON:
3545 response->set_losi(openolt::AlarmState::ON);
3546 break;
3547 case bcmolt_status::BCMOLT_STATUS_OFF:
3548 response->set_losi(openolt::AlarmState::OFF);
3549 break;
3550 }
3551
3552 switch (lofi)
3553 {
3554 case bcmolt_status::BCMOLT_STATUS_ON:
3555 response->set_lofi(openolt::AlarmState::ON);
3556 break;
3557 case bcmolt_status::BCMOLT_STATUS_OFF:
3558 response->set_lofi(openolt::AlarmState::OFF);
3559 break;
3560 }
3561
3562 switch (loami)
3563 {
3564 case bcmolt_status::BCMOLT_STATUS_ON:
3565 response->set_loami(openolt::AlarmState::ON);
3566 break;
3567 case bcmolt_status::BCMOLT_STATUS_OFF:
3568 response->set_loami(openolt::AlarmState::OFF);
3569 break;
3570 }
3571 return Status::OK;
3572 }
3573 else
3574 {
3575 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch Onu status, onu_id = %d, intf_id = %d, err = %s\n",
3576 onu_id, intf_id, bcmos_strerror(err));
3577 return bcm_to_grpc_err(err, "Failed to fetch Onu status");
3578 }
3579}
3580
3581Status GetPonInterfaceInfo_(uint32_t intf_id, openolt::PonIntfInfo *response)
3582{
3583 bcmos_errno err = BCM_ERR_OK;
3584
3585 bcmolt_status los_status;
3586 bcmolt_interface_state state;
3587 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
3588 OPENOLT_LOG(ERROR, openolt_log_id, "pon state %d\n",state);
3589 OPENOLT_LOG(ERROR, openolt_log_id, "pon los status %d\n", los_status);
3590
3591
3592 if (err == BCM_ERR_OK)
3593 {
3594 response->set_intf_id(intf_id) ;
3595 switch (los_status)
3596 {
3597 case bcmolt_status::BCMOLT_STATUS_ON:
3598
3599 response->set_los(openolt::AlarmState::ON);
3600 break;
3601 case bcmolt_status::BCMOLT_STATUS_OFF:
3602 response->set_los(openolt::AlarmState::OFF);
3603 break;
3604 }
3605
3606 switch (state)
3607 {
3608 case bcmolt_interface_state::BCMOLT_INTERFACE_STATE_ACTIVE_WORKING:
3609 response->set_state(openolt::PonIntfInfo_PonIntfState::PonIntfInfo_PonIntfState_ACTIVE_WORKING);
3610 break;
3611 case bcmolt_interface_state::BCMOLT_INTERFACE_STATE_ACTIVE_STANDBY:
3612 response->set_state(openolt::PonIntfInfo_PonIntfState::PonIntfInfo_PonIntfState_ACTIVE_STANDBY);
3613 break;
3614
3615 case bcmolt_interface_state::BCMOLT_INTERFACE_STATE_DISABLED:
3616 response->set_state(openolt::PonIntfInfo_PonIntfState::PonIntfInfo_PonIntfState_DISABLED);
3617 break;
3618
3619 case bcmolt_interface_state::BCMOLT_INTERFACE_STATE_INACTIVE:
3620
3621 response->set_state(openolt::PonIntfInfo_PonIntfState::PonIntfInfo_PonIntfState_INACTIVE);
3622 break;
3623 default:
3624 response->set_state(openolt::PonIntfInfo_PonIntfState::PonIntfInfo_PonIntfState_UNKNOWN);
3625 }
3626
3627 return Status::OK;
3628 }
3629 else
3630 {
3631 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch PON interface los status intf_id = %d, err = %s\n",
3632 intf_id, bcmos_strerror(err));
3633 return bcm_to_grpc_err(err, "Failed to fetch PON interface los status intf_id");
3634 }
3635}