blob: 15ed1ae7bfec712e3c1d3c2fed29a3c39a95c473 [file] [log] [blame]
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001/*
Girish Gowdraa707e7c2019-11-07 11:36:13 +05302 * Copyright 2018-present Open Networking Foundation
Shad Ansarib7b0ced2018-05-11 21:53:32 +00003
Girish Gowdraa707e7c2019-11-07 11:36:13 +05304 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
Shad Ansarib7b0ced2018-05-11 21:53:32 +00007
Girish Gowdraa707e7c2019-11-07 11:36:13 +05308 * http://www.apache.org/licenses/LICENSE-2.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00009
Girish Gowdraa707e7c2019-11-07 11:36:13 +053010 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +000016
17#include <iostream>
18#include <memory>
19#include <string>
20
21#include "Queue.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000022#include <sstream>
Nicolas Palpacuer9c352082018-08-14 16:37:14 -040023#include <chrono>
24#include <thread>
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080025#include <bitset>
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000026#include <inttypes.h>
Jason Huangbf45ffb2019-10-30 17:29:02 +080027#include <unistd.h>
Jason Huang09b73ea2020-01-08 17:52:05 +080028#include <sys/socket.h>
29#include <netinet/in.h>
30#include <arpa/inet.h>
Shad Ansarib7b0ced2018-05-11 21:53:32 +000031
Craig Lutgen88a22ad2018-10-04 12:30:46 -050032#include "device.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000033#include "core.h"
Girish Gowdraddf9a162020-01-27 12:56:27 +053034#include "core_data.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000035#include "indications.h"
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -040036#include "stats_collection.h"
Nicolas Palpacuer73222e02018-07-16 12:20:26 -040037#include "error_format.h"
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -040038#include "state.h"
Girish Gowdraddf9a162020-01-27 12:56:27 +053039#include "core_utils.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000040
41extern "C"
42{
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000043#include <bcmolt_api.h>
44#include <bcmolt_host_api.h>
45#include <bcmolt_api_model_supporting_enums.h>
46
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000047#include <bcmolt_api_conn_mgr.h>
48//CLI header files
49#include <bcmcli_session.h>
50#include <bcmcli.h>
51#include <bcm_api_cli.h>
52
53#include <bcmos_common.h>
54#include <bcm_config.h>
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -040055// FIXME : dependency problem
56// #include <bcm_common_gpon.h>
Nicolas Palpacuer967438f2018-09-07 14:41:54 -040057// #include <bcm_dev_log_task.h>
Shad Ansarib7b0ced2018-05-11 21:53:32 +000058}
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000059
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000060static std::string intf_technologies[MAX_SUPPORTED_PON];
Craig Lutgen88a22ad2018-10-04 12:30:46 -050061static const std::string UNKNOWN_TECH("unknown");
Craig Lutgenb2601f02018-10-23 13:04:31 -050062static const std::string MIXED_TECH("mixed");
63static std::string board_technology(UNKNOWN_TECH);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000064static std::string chip_family(UNKNOWN_TECH);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000065static std::string firmware_version = "Openolt.2019.07.01";
Nicolas Palpacuerdff96792018-09-06 14:59:32 -040066
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080067static bcmos_errno CreateSched(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
Girish Gowdra252f4972020-09-07 21:24:01 -070068 uint32_t port_no, uint32_t alloc_id, ::tech_profile::AdditionalBW additional_bw, uint32_t weight, \
69 uint32_t priority, ::tech_profile::SchedulingPolicy sched_policy,
70 ::tech_profile::TrafficShapingInfo traffic_shaping_info, uint32_t tech_profile_id);
Burak Gurdag2f2618c2020-04-23 13:20:30 +000071static bcmos_errno RemoveSched(int intf_id, int onu_id, int uni_id, int alloc_id, std::string direction, int tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080072static bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +000073 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id, uint32_t tech_profile_id);
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -050074static bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +000075 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id, uint32_t tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000076static bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction);
77static bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction);
Orhan Kupusogluec57af02021-05-12 12:38:17 +000078static const std::chrono::milliseconds ONU_RSSI_COMPLETE_WAIT_TIMEOUT = std::chrono::seconds(10);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000079
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000080inline const char *get_flow_acton_command(uint32_t command) {
81 char actions[200] = { };
82 char *s_actions_ptr = actions;
83 if (command & BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG) strcat(s_actions_ptr, "ADD_OUTER_TAG|");
84 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG) strcat(s_actions_ptr, "REMOVE_OUTER_TAG|");
85 if (command & BCMOLT_ACTION_CMD_ID_XLATE_OUTER_TAG) strcat(s_actions_ptr, "TRANSLATE_OUTER_TAG|");
86 if (command & BCMOLT_ACTION_CMD_ID_ADD_INNER_TAG) strcat(s_actions_ptr, "ADD_INNTER_TAG|");
87 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_INNER_TAG) strcat(s_actions_ptr, "REMOVE_INNER_TAG|");
88 if (command & BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG) strcat(s_actions_ptr, "TRANSLATE_INNER_TAG|");
89 if (command & BCMOLT_ACTION_CMD_ID_REMARK_OUTER_PBITS) strcat(s_actions_ptr, "REMOVE_OUTER_PBITS|");
90 if (command & BCMOLT_ACTION_CMD_ID_REMARK_INNER_PBITS) strcat(s_actions_ptr, "REMAKE_INNER_PBITS|");
91 return s_actions_ptr;
92}
93
kesavandc1f2db92020-08-31 15:32:06 +053094bcmolt_stat_alarm_config set_stat_alarm_config(const config::OnuItuPonAlarm* request) {
Jason Huang5d9ab1a2020-04-15 16:53:49 +080095 bcmolt_stat_alarm_config alarm_cfg = {};
96 bcmolt_stat_alarm_trigger_config trigger_obj = {};
97 bcmolt_stat_alarm_soak_config soak_obj = {};
98
99 switch (request->alarm_reporting_condition()) {
kesavandc1f2db92020-08-31 15:32:06 +0530100 case config::OnuItuPonAlarm::RATE_THRESHOLD:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800101 trigger_obj.type = BCMOLT_STAT_CONDITION_TYPE_RATE_THRESHOLD;
102 BCMOLT_FIELD_SET(&trigger_obj.u.rate_threshold, stat_alarm_trigger_config_rate_threshold,
103 rising, request->rate_threshold_config().rate_threshold_rising());
104 BCMOLT_FIELD_SET(&trigger_obj.u.rate_threshold, stat_alarm_trigger_config_rate_threshold,
105 falling, request->rate_threshold_config().rate_threshold_falling());
106 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, active_soak_time,
107 request->rate_threshold_config().soak_time().active_soak_time());
108 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, clear_soak_time,
109 request->rate_threshold_config().soak_time().clear_soak_time());
110 break;
kesavandc1f2db92020-08-31 15:32:06 +0530111 case config::OnuItuPonAlarm::RATE_RANGE:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800112 trigger_obj.type = BCMOLT_STAT_CONDITION_TYPE_RATE_RANGE;
113 BCMOLT_FIELD_SET(&trigger_obj.u.rate_range, stat_alarm_trigger_config_rate_range, upper,
114 request->rate_range_config().rate_range_upper());
115 BCMOLT_FIELD_SET(&trigger_obj.u.rate_range, stat_alarm_trigger_config_rate_range, lower,
116 request->rate_range_config().rate_range_lower());
117 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, active_soak_time,
118 request->rate_range_config().soak_time().active_soak_time());
119 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, clear_soak_time,
120 request->rate_range_config().soak_time().clear_soak_time());
121 break;
kesavandc1f2db92020-08-31 15:32:06 +0530122 case config::OnuItuPonAlarm::VALUE_THRESHOLD:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800123 trigger_obj.type = BCMOLT_STAT_CONDITION_TYPE_VALUE_THRESHOLD;
124 BCMOLT_FIELD_SET(&trigger_obj.u.value_threshold, stat_alarm_trigger_config_value_threshold,
125 limit, request->value_threshold_config().threshold_limit());
126 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, active_soak_time,
127 request->value_threshold_config().soak_time().active_soak_time());
128 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, clear_soak_time,
129 request->value_threshold_config().soak_time().clear_soak_time());
130 break;
131 default:
132 OPENOLT_LOG(ERROR, openolt_log_id, "unsupported alarm reporting condition = %u\n", request->alarm_reporting_condition());
133 // For now just log the error and not return error. We can handle this scenario in the future.
134 break;
135 }
136
137 BCMOLT_FIELD_SET(&alarm_cfg, stat_alarm_config, trigger, trigger_obj);
138 BCMOLT_FIELD_SET(&alarm_cfg, stat_alarm_config, soak, soak_obj);
139
140 return alarm_cfg;
141}
142
kesavandc1f2db92020-08-31 15:32:06 +0530143Status OnuItuPonAlarmSet_(const config::OnuItuPonAlarm* request) {
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800144 bcmos_errno err;
145 bcmolt_onu_itu_pon_stats_cfg stat_cfg; /* declare main API struct */
146 bcmolt_onu_key key = {}; /* declare key */
147 bcmolt_stat_alarm_config errors_cfg = {};
148
149 key.pon_ni = request->pon_ni();
150 key.onu_id = request->onu_id();
151
152 /* Initialize the API struct. */
153 BCMOLT_STAT_CFG_INIT(&stat_cfg, onu, itu_pon_stats, key);
154
155 /*
156 1. BCMOLT_STAT_CONDITION_TYPE_NONE = 0, The alarm is disabled.
157 2. BCMOLT_STAT_CONDITION_TYPE_RATE_THRESHOLD = 1, The alarm is triggered if the stats delta value between samples
158 crosses the configured threshold boundary.
159 rising: The alarm is raised if the stats delta value per second becomes greater than this threshold level.
160 falling: The alarm is cleared if the stats delta value per second becomes less than this threshold level.
161 3. BCMOLT_STAT_CONDITION_TYPE_RATE_RANGE = 2, The alarm is triggered if the stats delta value between samples
162 deviates from the configured range.
163 upper: The alarm is raised if the stats delta value per second becomes greater than this upper level.
164 lower: The alarm is raised if the stats delta value per second becomes less than this lower level.
165 4. BCMOLT_STAT_CONDITION_TYPE_VALUE_THRESHOLD = 3, The alarm is raised if the stats sample value becomes greater
166 than this level. The alarm is cleared when the host read the stats.
167 limit: The alarm is raised if the stats sample value becomes greater than this level.
168 The alarm is cleared when the host clears the stats.
169
170 active_soak_time: If the alarm condition is raised and stays in the raised state for at least this amount
171 of time (unit=seconds), the alarm indication is sent to the host.
172 The OLT delays the alarm indication no less than this delay period.
173 It can be delayed more than this period because of the statistics sampling interval.
174 clear_soak_time: After the alarm is raised, if it is cleared and stays in the cleared state for at least
175 this amount of time (unit=seconds), the alarm indication is sent to the host.
176 The OLT delays the alarm indication no less than this delay period. It can be delayed more
177 than this period because of the statistics sampling interval.
178 */
179
180 errors_cfg = set_stat_alarm_config(request);
181
182 switch (request->alarm_id()) {
kesavandc1f2db92020-08-31 15:32:06 +0530183 case config::OnuItuPonAlarm_AlarmID::OnuItuPonAlarm_AlarmID_RDI_ERRORS:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800184 //set the rdi_errors alarm
185 BCMOLT_FIELD_SET(&stat_cfg.data, onu_itu_pon_stats_cfg_data, rdi_errors, errors_cfg);
186 break;
187 default:
188 OPENOLT_LOG(ERROR, openolt_log_id, "could not find the alarm id %d\n", request->alarm_id());
189 return bcm_to_grpc_err(BCM_ERR_PARM, "the alarm id is wrong");
190 }
191
192 err = bcmolt_stat_cfg_set(dev_id, &stat_cfg.hdr);
193 if (err != BCM_ERR_OK) {
194 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",
195 request->alarm_id(), key.pon_ni, key.onu_id, bcmos_strerror(err));
196 return bcm_to_grpc_err(err, "set Onu ITU PON stats alarm faild");
197 } else {
198 OPENOLT_LOG(INFO, openolt_log_id, "set onu itu pon stats alarm %d successfully, pon_ni %d, onu_id %d\n",
199 request->alarm_id(), key.pon_ni, key.onu_id);
200 }
201
202 return Status::OK;
203}
204
Girish Gowdra252f4972020-09-07 21:24:01 -0700205Status GetDeviceInfo_(::openolt::DeviceInfo* device_info) {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500206 device_info->set_vendor(VENDOR_ID);
207 device_info->set_model(MODEL_ID);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400208 device_info->set_hardware_version("");
209 device_info->set_firmware_version(firmware_version);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500210 device_info->set_technology(board_technology);
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);
240
Craig Lutgenb2601f02018-10-23 13:04:31 -0500241 // Legacy, device-wide ranges. To be deprecated when adapter
242 // is upgraded to support per-interface ranges
Girish Gowdra252f4972020-09-07 21:24:01 -0700243 device_info->set_onu_id_start(ONU_ID_START);
244 device_info->set_onu_id_end(ONU_ID_END);
245 device_info->set_alloc_id_start(ALLOC_ID_START);
246 device_info->set_alloc_id_end(ALLOC_ID_END);
247 device_info->set_gemport_id_start(GEM_PORT_ID_START);
248 device_info->set_gemport_id_end(GEM_PORT_ID_END);
249 device_info->set_flow_id_start(FLOW_ID_START);
250 device_info->set_flow_id_end(FLOW_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500251
Girish Gowdra252f4972020-09-07 21:24:01 -0700252 std::map<std::string, ::openolt::DeviceInfo::DeviceResourceRanges*> ranges;
Craig Lutgenb2601f02018-10-23 13:04:31 -0500253 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
254 std::string intf_technology = intf_technologies[intf_id];
Girish Gowdra252f4972020-09-07 21:24:01 -0700255 ::openolt::DeviceInfo::DeviceResourceRanges *range = ranges[intf_technology];
Craig Lutgenb2601f02018-10-23 13:04:31 -0500256 if(range == nullptr) {
257 range = device_info->add_ranges();
258 ranges[intf_technology] = range;
259 range->set_technology(intf_technology);
260
Girish Gowdra252f4972020-09-07 21:24:01 -0700261 ::openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
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::ONU_ID);
265 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
266 pool->set_start(ONU_ID_START);
267 pool->set_end(ONU_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::ALLOC_ID);
271 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
272 pool->set_start(ALLOC_ID_START);
Girish Gowdraeec0fc92021-05-12 15:37:55 -0700273 pool->set_end(ALLOC_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500274
Girish Gowdra252f4972020-09-07 21:24:01 -0700275 pool = range->add_pools();
276 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
277 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
278 pool->set_start(GEM_PORT_ID_START);
279 pool->set_end(GEM_PORT_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500280
Girish Gowdra252f4972020-09-07 21:24:01 -0700281 pool = range->add_pools();
282 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
283 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
284 pool->set_start(FLOW_ID_START);
285 pool->set_end(FLOW_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500286 }
287
288 range->add_intf_ids(intf_id);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500289 }
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400290
291 // FIXME: Once dependency problem is fixed
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500292 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400293 // device_info->set_onu_id_end(XGPON_NUM_OF_ONUS - 1);
294 // device_info->set_alloc_id_start(1024);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500295 // device_info->set_alloc_id_end(XGPON_NUM_OF_ALLOC_IDS * num_of_pon_ports ? - 1);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400296 // device_info->set_gemport_id_start(XGPON_MIN_BASE_SERVICE_PORT_ID);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500297 // device_info->set_gemport_id_end(XGPON_NUM_OF_GEM_PORT_IDS_PER_PON * num_of_pon_ports ? - 1);
298 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400299
300 return Status::OK;
301}
302
Thiyagarajan Subramani3e8bfd92021-04-26 15:07:14 +0530303void reset_pon_device(bcmolt_odid dev)
304{
305 bcmos_errno err;
306 bcmolt_device_reset oper;
307 bcmolt_device_key key = {.device_id = dev};
308
309 OPENOLT_LOG(INFO, openolt_log_id, "Reset PON device: %d\n", dev);
310
311 BCMOLT_OPER_INIT(&oper, device, reset, key);
312 err = bcmolt_oper_submit(dev_id, &oper.hdr);
313 if (err)
314 {
315 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to reset PON device(%d) failed, err = %s\n", dev, bcmos_strerror(err));
316 }else
317 {
318 OPENOLT_LOG(INFO, openolt_log_id, "Reset PON device(%d) success\n", dev);
319 }
320}
321
Shad Ansari627b5782018-08-13 22:49:32 +0000322Status Enable_(int argc, char *argv[]) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000323 bcmos_errno err;
324 bcmolt_host_init_parms init_parms = {};
325 init_parms.transport.type = BCM_HOST_API_CONN_LOCAL;
326 unsigned int failed_enable_device_cnt = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000327
Shad Ansariedef2132018-08-10 22:14:50 +0000328 if (!state.is_activated()) {
Shad Ansari627b5782018-08-13 22:49:32 +0000329
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500330 vendor_init();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000331 /* Initialize host subsystem */
332 err = bcmolt_host_init(&init_parms);
333 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500334 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to init OLT, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000335 return bcm_to_grpc_err(err, "Failed to init OLT");
336 }
337
338 bcmcli_session_parm mon_session_parm;
339 /* Create CLI session */
340 memset(&mon_session_parm, 0, sizeof(mon_session_parm));
341 mon_session_parm.get_prompt = openolt_cli_get_prompt_cb;
342 mon_session_parm.access_right = BCMCLI_ACCESS_ADMIN;
343 bcmos_errno rc = bcmcli_session_open(&mon_session_parm, &current_session);
344 BUG_ON(rc != BCM_ERR_OK);
345
346 /* API CLI */
347 bcm_openolt_api_cli_init(NULL, current_session);
348
349 /* Add quit command */
350 BCMCLI_MAKE_CMD_NOPARM(NULL, "quit", "Quit", bcm_cli_quit);
351
352 err = bcmolt_apiend_cli_init();
353 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500354 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to add apiend init, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000355 return bcm_to_grpc_err(err, "Failed to add apiend init");
356 }
357
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800358 bcmos_fastlock_init(&data_lock, 0);
Girish Gowdra252f4972020-09-07 21:24:01 -0700359 bcmos_fastlock_init(&acl_id_bitset_lock, 0);
360 bcmos_fastlock_init(&tm_sched_bitset_lock, 0);
361 bcmos_fastlock_init(&tm_qmp_bitset_lock, 0);
362 bcmos_fastlock_init(&flow_id_bitset_lock, 0);
363 bcmos_fastlock_init(&voltha_flow_to_device_flow_lock, 0);
Girish Gowdra96461052019-11-22 20:13:59 +0530364 bcmos_fastlock_init(&alloc_cfg_wait_lock, 0);
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +0530365 bcmos_fastlock_init(&gem_cfg_wait_lock, 0);
Girish Gowdra7a79dae2020-02-10 18:22:11 +0530366 bcmos_fastlock_init(&onu_deactivate_wait_lock, 0);
Girish Gowdra1935e6a2020-10-31 21:48:22 -0700367 bcmos_fastlock_init(&acl_packet_trap_handler_lock, 0);
Girish Gowdraeec0fc92021-05-12 15:37:55 -0700368 bcmos_fastlock_init(&symmetric_datapath_flow_id_lock, 0);
369 bcmos_fastlock_init(&pon_gem_to_onu_uni_map_lock, 0);
370
Girish Gowdra1935e6a2020-10-31 21:48:22 -0700371
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000372 OPENOLT_LOG(INFO, openolt_log_id, "Enable OLT - %s-%s\n", VENDOR_ID, MODEL_ID);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600373
Jason Huangbf45ffb2019-10-30 17:29:02 +0800374 //check BCM daemon is connected or not
375 Status status = check_connection();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000376 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800377 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000378 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800379 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000380 Status status = SubscribeIndication();
381 if (!status.ok()) {
382 OPENOLT_LOG(ERROR, openolt_log_id, "SubscribeIndication failed - %s : %s\n",
383 grpc_status_code_to_string(status.error_code()).c_str(),
384 status.error_message().c_str());
385 return status;
386 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800387
388 //check BAL state in initial stage
389 status = check_bal_ready();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000390 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800391 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000392 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800393 }
394
395 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000396 bcmos_errno err;
397 bcmolt_odid dev;
398 OPENOLT_LOG(INFO, openolt_log_id, "Enabling PON %d Devices ... \n", BCM_MAX_DEVS_PER_LINE_CARD);
399 for (dev = 0; dev < BCM_MAX_DEVS_PER_LINE_CARD; dev++) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400400 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000401 bcmolt_device_key dev_key = { };
402 dev_key.device_id = dev;
403 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
404 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Thiyagarajan Subramani4e62e172021-06-25 17:31:30 +0530405
406 /* FIXME: Single Phoenix BAL patch is prepared for all three variants of Radisys OLT
407 * in which BCM_MAX_DEVS_PER_LINE_CARD macro need to be redefined as 1 incase of
408 * "rlt-1600g-w" and "rlt-1600x-w", till then this workaround is required.*/
409 if (dev == 1 && (MODEL_ID == "rlt-1600g-w" || MODEL_ID == "rlt-1600x-w")) {
410 continue;
411 }
412
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000413 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
Jason Huangbf45ffb2019-10-30 17:29:02 +0800414 if (err == BCM_ERR_NOT_CONNECTED) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000415 bcmolt_device_key key = {.device_id = dev};
416 bcmolt_device_connect oper;
417 BCMOLT_OPER_INIT(&oper, device, connect, key);
Thiyagarajan Subramani3e8bfd92021-04-26 15:07:14 +0530418
419 /* BAL saves current state into dram_tune soc file and when dev_mgmt_daemon restarts
420 * it retains config from soc file. If openolt agent try to connect device without
421 * device reset device initialization fails hence doing device reset here. */
422 reset_pon_device(dev);
423
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000424 if (MODEL_ID == "asfvolt16") {
425 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
426 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_XGS__2_X);
427 } else if (MODEL_ID == "asgvolt64") {
428 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
429 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
430 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
Thiyagarajan Subramani4e62e172021-06-25 17:31:30 +0530431 } else if (MODEL_ID == "rlt-3200g-w" || MODEL_ID == "rlt-1600g-w") {
Thiyagarajan Subramani3e8bfd92021-04-26 15:07:14 +0530432 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_NONE);
433 if(dev == 1) {
434 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
435 }
436 BCMOLT_MSG_FIELD_SET (&oper, ras_ddr_mode, BCMOLT_RAS_DDR_USAGE_MODE_TWO_DDRS);
437 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
438 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
Thiyagarajan Subramani4e62e172021-06-25 17:31:30 +0530439 } else if (MODEL_ID == "rlt-1600x-w") {
440 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_NONE);
441 BCMOLT_MSG_FIELD_SET (&oper, ras_ddr_mode, BCMOLT_RAS_DDR_USAGE_MODE_TWO_DDRS);
442 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
443 /* By default setting device mode to GPON for rlt 1600x.
444 In future device mode can be configured to XGSPON || GPON by reading
445 device mode configuration from a static configuration file*/
446 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000447 }
448 err = bcmolt_oper_submit(dev_id, &oper.hdr);
449 if (err) {
450 failed_enable_device_cnt ++;
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500451 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 +0000452 if (failed_enable_device_cnt == BCM_MAX_DEVS_PER_LINE_CARD) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500453 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 +0000454 return Status(grpc::StatusCode::INTERNAL, "Failed to activate all PON ports");
455 }
456 }
Girish Gowdra72bb4652022-01-18 17:04:30 -0800457 bcmos_usleep(MAC_DEVICE_ACTIVATION_DELAY);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000458 }
459 else {
Thiyagarajan Subramani4e62e172021-06-25 17:31:30 +0530460 OPENOLT_LOG(WARNING, openolt_log_id, "PON device %d already connected\n", dev);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000461 state.activate();
462 }
463 }
464 init_stats();
Shad Ansari627b5782018-08-13 22:49:32 +0000465 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000466 }
Shad Ansariedef2132018-08-10 22:14:50 +0000467
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000468 /* Start CLI */
469 OPENOLT_LOG(INFO, def_log_id, "Starting CLI\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400470 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000471 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400472}
473
474Status Disable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400475 //In the earlier implementation Disabling olt is done by disabling the NNI port associated with that.
476 //In inband scenario instead of using management interface to establish connection with adapter ,NNI interface will be used.
477 //Disabling NNI port on olt disable causes connection loss between adapter and agent.
478 //To overcome this disable is implemented by disabling all the PON ports
479 //associated with the device so as to support both in-band
480 //and out of band scenarios.
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400481
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400482 Status status;
483 int failedCount = 0;
Girish Gowdrae1db2952021-05-04 00:16:54 -0700484 OPENOLT_LOG(INFO, openolt_log_id, "Received disable OLT\n");
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400485 for (int i = 0; i < NumPonIf_(); i++) {
486 status = DisablePonIf_(i);
487 if (!status.ok()) {
488 failedCount+=1;
489 BCM_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", i);
490 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400491 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400492 if (failedCount == 0) {
493 state.deactivate();
Girish Gowdra252f4972020-09-07 21:24:01 -0700494 ::openolt::Indication ind;
495 ::openolt::OltIndication* olt_ind = new ::openolt::OltIndication;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400496 olt_ind->set_oper_state("down");
497 ind.set_allocated_olt_ind(olt_ind);
498 BCM_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
499 oltIndQ.push(ind);
500 return Status::OK;
501 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000502 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400503 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to disable olt ,all the PON ports are still in enabled state");
504 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400505
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400506 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 -0400507}
508
509Status Reenable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400510 Status status;
511 int failedCount = 0;
512 for (int i = 0; i < NumPonIf_(); i++) {
513 status = EnablePonIf_(i);
514 if (!status.ok()) {
515 failedCount+=1;
516 BCM_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", i);
517 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400518 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000519 if (failedCount == 0) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400520 state.activate();
Girish Gowdra252f4972020-09-07 21:24:01 -0700521 ::openolt::Indication ind;
522 ::openolt::OltIndication* olt_ind = new ::openolt::OltIndication;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400523 olt_ind->set_oper_state("up");
524 ind.set_allocated_olt_ind(olt_ind);
525 BCM_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
526 oltIndQ.push(ind);
527 return Status::OK;
528 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000529 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400530 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to re-enable olt ,all the PON ports are still in disabled state");
531 }
532 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 +0000533}
534
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000535inline uint64_t get_flow_status(uint16_t flow_id, uint16_t flow_type, uint16_t data_id) {
536 bcmos_errno err;
537 bcmolt_flow_key flow_key;
538 bcmolt_flow_cfg flow_cfg;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400539
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000540 flow_key.flow_id = flow_id;
541 flow_key.flow_type = (bcmolt_flow_type)flow_type;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400542
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000543 BCMOLT_CFG_INIT(&flow_cfg, flow, flow_key);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400544
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000545 switch (data_id) {
546 case ONU_ID: //onu_id
547 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, onu_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500548 #ifdef TEST_MODE
549 // It is impossible to mock the setting of flow_cfg.data.state because
550 // the actual bcmolt_cfg_get passes the address of flow_cfg.hdr and we cannot
551 // set the flow_cfg.data. So a new stub function is created and address
552 // of flow_cfg is passed. This is one-of case where we need to add test specific
553 // code in production code.
554 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
555 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000556 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500557 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000558 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700559 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 +0000560 return err;
561 }
562 return flow_cfg.data.onu_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400563 case FLOW_TYPE:
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500564 #ifdef TEST_MODE
565 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
566 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000567 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500568 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000569 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700570 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 +0000571 return err;
572 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400573 return flow_cfg.key.flow_type;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000574 case SVC_PORT_ID: //svc_port_id
575 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, svc_port_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500576 #ifdef TEST_MODE
577 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
578 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000579 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500580 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000581 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700582 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 +0000583 return err;
584 }
585 return flow_cfg.data.svc_port_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400586 case PRIORITY:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000587 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, priority);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500588 #ifdef TEST_MODE
589 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
590 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000591 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500592 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000593 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700594 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 +0000595 return err;
596 }
597 return flow_cfg.data.priority;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400598 case COOKIE: //cookie
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000599 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, cookie);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500600 #ifdef TEST_MODE
601 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
602 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000603 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500604 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000605 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700606 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 +0000607 return err;
608 }
609 return flow_cfg.data.cookie;
610 case INGRESS_INTF_TYPE: //ingress intf_type
611 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500612 #ifdef TEST_MODE
613 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
614 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000615 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500616 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000617 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700618 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 +0000619 return err;
620 }
621 return flow_cfg.data.ingress_intf.intf_type;
622 case EGRESS_INTF_TYPE: //egress intf_type
623 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500624 #ifdef TEST_MODE
625 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
626 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000627 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500628 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000629 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700630 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 +0000631 return err;
632 }
633 return flow_cfg.data.egress_intf.intf_type;
634 case INGRESS_INTF_ID: //ingress intf_id
635 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500636 #ifdef TEST_MODE
637 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
638 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000639 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500640 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000641 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700642 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 +0000643 return err;
644 }
645 return flow_cfg.data.ingress_intf.intf_id;
646 case EGRESS_INTF_ID: //egress intf_id
647 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500648 #ifdef TEST_MODE
649 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
650 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000651 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500652 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000653 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700654 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 +0000655 return err;
656 }
657 return flow_cfg.data.egress_intf.intf_id;
658 case CLASSIFIER_O_VID:
659 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500660 #ifdef TEST_MODE
661 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
662 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000663 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500664 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000665 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700666 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 +0000667 return err;
668 }
669 return flow_cfg.data.classifier.o_vid;
670 case CLASSIFIER_O_PBITS:
671 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500672 #ifdef TEST_MODE
673 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
674 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000675 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500676 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000677 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700678 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 +0000679 return err;
680 }
681 return flow_cfg.data.classifier.o_pbits;
682 case CLASSIFIER_I_VID:
683 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500684 #ifdef TEST_MODE
685 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
686 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000687 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500688 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000689 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700690 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 +0000691 return err;
692 }
693 return flow_cfg.data.classifier.i_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400694 case CLASSIFIER_I_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000695 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500696 #ifdef TEST_MODE
697 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
698 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000699 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500700 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000701 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700702 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 +0000703 return err;
704 }
705 return flow_cfg.data.classifier.i_pbits;
706 case CLASSIFIER_ETHER_TYPE:
707 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500708 #ifdef TEST_MODE
709 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
710 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000711 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500712 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000713 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700714 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 +0000715 return err;
716 }
717 return flow_cfg.data.classifier.ether_type;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400718 case CLASSIFIER_IP_PROTO:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000719 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500720 #ifdef TEST_MODE
721 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
722 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000723 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500724 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000725 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700726 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 +0000727 return err;
728 }
729 return flow_cfg.data.classifier.ip_proto;
730 case CLASSIFIER_SRC_PORT:
731 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500732 #ifdef TEST_MODE
733 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
734 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000735 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500736 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000737 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700738 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 +0000739 return err;
740 }
741 return flow_cfg.data.classifier.src_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400742 case CLASSIFIER_DST_PORT:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000743 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500744 #ifdef TEST_MODE
745 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
746 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000747 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500748 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000749 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700750 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 +0000751 return err;
752 }
753 return flow_cfg.data.classifier.dst_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400754 case CLASSIFIER_PKT_TAG_TYPE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000755 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500756 #ifdef TEST_MODE
757 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
758 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000759 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500760 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000761 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700762 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 +0000763 return err;
764 }
765 return flow_cfg.data.classifier.pkt_tag_type;
766 case EGRESS_QOS_TYPE:
767 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500768 #ifdef TEST_MODE
769 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
770 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000771 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500772 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000773 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700774 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 +0000775 return err;
776 }
777 return flow_cfg.data.egress_qos.type;
778 case EGRESS_QOS_QUEUE_ID:
779 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500780 #ifdef TEST_MODE
781 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
782 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000783 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500784 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000785 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700786 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 +0000787 return err;
788 }
789 switch (flow_cfg.data.egress_qos.type) {
790 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE:
791 return flow_cfg.data.egress_qos.u.fixed_queue.queue_id;
792 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE:
793 return flow_cfg.data.egress_qos.u.tc_to_queue.tc_to_queue_id;
794 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC:
795 return flow_cfg.data.egress_qos.u.pbit_to_tc.tc_to_queue_id;
796 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE:
797 return flow_cfg.data.egress_qos.u.priority_to_queue.tm_q_set_id;
798 case BCMOLT_EGRESS_QOS_TYPE_NONE:
799 default:
800 return -1;
801 }
802 case EGRESS_QOS_TM_SCHED_ID:
803 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500804 #ifdef TEST_MODE
805 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
806 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000807 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500808 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000809 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700810 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 +0000811 return err;
812 }
813 return flow_cfg.data.egress_qos.tm_sched.id;
814 case ACTION_CMDS_BITMASK:
815 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500816 #ifdef TEST_MODE
817 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
818 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000819 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500820 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000821 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700822 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 +0000823 return err;
824 }
825 return flow_cfg.data.action.cmds_bitmask;
826 case ACTION_O_VID:
827 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500828 #ifdef TEST_MODE
829 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
830 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000831 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500832 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000833 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700834 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 +0000835 return err;
836 }
837 return flow_cfg.data.action.o_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400838 case ACTION_O_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000839 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500840 #ifdef TEST_MODE
841 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
842 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000843 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500844 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000845 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700846 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 +0000847 return err;
848 }
849 return flow_cfg.data.action.o_pbits;
850 case ACTION_I_VID:
851 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500852 #ifdef TEST_MODE
853 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
854 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000855 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500856 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000857 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700858 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 +0000859 return err;
860 }
861 return flow_cfg.data.action.i_vid;
862 case ACTION_I_PBITS:
863 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500864 #ifdef TEST_MODE
865 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
866 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000867 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500868 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000869 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700870 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 +0000871 return err;
872 }
873 return flow_cfg.data.action.i_pbits;
874 case STATE:
875 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, state);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500876 #ifdef TEST_MODE
877 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
878 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000879 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500880 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000881 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700882 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 +0000883 return err;
884 }
885 return flow_cfg.data.state;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000886 case GROUP_ID:
887 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, group_id);
888 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
889 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700890 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 +0000891 return err;
892 }
893 return flow_cfg.data.group_id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000894 default:
895 return BCM_ERR_INTERNAL;
896 }
897
898 return err;
899}
900
901Status EnablePonIf_(uint32_t intf_id) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400902 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000903 bcmolt_pon_interface_cfg interface_obj;
904 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
905 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
906 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530907 bcmolt_status los_status;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000908
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530909 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000910 if (err == BCM_ERR_OK) {
911 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800912 OPENOLT_LOG(WARNING, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000913 return Status::OK;
914 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400915 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000916 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
917 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
918 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
919 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.interval, 5000);
920 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.onu_post_discovery_mode,
Girish Gowdra24297032020-03-23 12:32:37 -0700921 BCMOLT_ONU_POST_DISCOVERY_MODE_NONE);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000922 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.los, true);
923 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.onu_alarms, true);
924 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.tiwi, true);
925 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.ack_timeout, true);
926 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.sfi, true);
927 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.loki, true);
Burak Gurdag5e587792020-05-06 14:58:02 +0000928
929 // On GPON, power level mode is not set to its default value (i.e. 0) as documented in Broadcom documentation.
930 // Instead, it is set to 2 which means -6 dbM attenuation. Therefore, we explicitly set it to the default value below.
931 if (board_technology == "GPON") {
932 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.pls_maximum_allocation_size, BCMOLT_PON_POWER_LEVEL_PLS_MAXIMUM_ALLOCATION_SIZE_DEFAULT);
933 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.mode, BCMOLT_PON_POWER_LEVEL_MODE_DEFAULT);
934 }
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;
1039 }
1040
1041 switch(dev_cfg.data.chip_family) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001042 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X: chip_family = "Maple"; break;
1043 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X: chip_family = "Aspen"; break;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001044 }
1045
Jason Huang09b73ea2020-01-08 17:52:05 +08001046 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s, family: %s, board_technology: %s\n",
1047 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 +00001048
1049 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001050 }
1051
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001052 /* 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 +00001053 only the devices that retured success*/
1054 if (num_failed_cfg_gets == BCM_MAX_DEVS_PER_LINE_CARD) {
1055 OPENOLT_LOG(ERROR, openolt_log_id, "device: Query of all the devices failed\n");
1056 return bcm_to_grpc_err(err, "device: All devices failed query");
1057 }
1058
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001059 return Status::OK;
1060}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001061
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001062Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001063 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001064 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
1065 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
1066 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001067
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001068 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001069 if (err == BCM_ERR_OK) {
1070 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001071 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001072 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1073 CreateDefaultSched(intf_id, upstream);
1074 CreateDefaultQueue(intf_id, upstream);
1075 return Status::OK;
1076 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1077 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
1078 return Status::OK;
1079 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001080 }
1081
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001082 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
1083 if (set_state) {
1084 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1085 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1086 } else {
1087 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1088 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1089 }
1090 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
1091 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001092 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err = %s\n",
1093 (set_state)?"enable":"disable", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001094 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
1095 }
1096 else {
1097 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
1098 if (set_state) {
1099 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1100 CreateDefaultSched(intf_id, upstream);
1101 CreateDefaultQueue(intf_id, upstream);
1102 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001103 }
1104
1105 return Status::OK;
1106}
1107
Elia Battiston869a5de2022-02-08 11:40:58 +01001108uint32_t GetNniSpeed_(uint32_t intf_id) {
1109 bcmos_errno err = BCM_ERR_OK;
1110
1111 uint32_t speed;
1112 err = get_nni_interface_speed((bcmolt_interface)intf_id, &speed);
1113 if (err != BCM_ERR_OK) {
1114 OPENOLT_LOG(WARNING, openolt_log_id, "Failed to read speed of NNI interface: %d\n", intf_id);
1115 return 0; //This will cause the adapter to use the default speed value
1116 }
1117
1118 return speed;
1119}
1120
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001121Status DisablePonIf_(uint32_t intf_id) {
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001122 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001123 bcmolt_pon_interface_cfg interface_obj;
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001124 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1125 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001126
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001127 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
Girish Gowdrae1db2952021-05-04 00:16:54 -07001128 BCMOLT_MSG_FIELD_GET(&interface_obj, state);
1129
1130 err = bcmolt_cfg_get(dev_id, &interface_obj.hdr);
1131 if (err != BCM_ERR_OK) {
1132 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);
1133 return bcm_to_grpc_err(err, "Failed to fetch pon port state");
1134 }
1135 if (interface_obj.data.state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1136 OPENOLT_LOG(INFO, openolt_log_id, "PON Interface already inactive, PON interface %d\n", intf_id);
1137 return Status::OK;
1138 }
1139
1140 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001141 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1142 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_DISABLE);
1143
1144 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1145 if (err != BCM_ERR_OK) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07001146 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 -05001147 return bcm_to_grpc_err(err, "Failed to disable discovery of onu");
1148 }
1149
1150 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1151 operation, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1152
1153 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1154 if (err != BCM_ERR_OK) {
1155 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 -04001156 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001157 }
1158
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001159 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled PON interface: %d\n", intf_id);
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001160 return Status::OK;
1161}
1162
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001163Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
kesavandc1f2db92020-08-31 15:32:06 +05301164 const char *vendor_id, const char *vendor_specific, uint32_t pir, bool omcc_encryption_mode) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001165 bcmos_errno err = BCM_ERR_OK;
1166 bcmolt_onu_cfg onu_cfg;
1167 bcmolt_onu_key onu_key;
1168 bcmolt_serial_number serial_number; /**< ONU serial number */
1169 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001170
Girish Gowdra24297032020-03-23 12:32:37 -07001171 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1172 bcmolt_onu_state onu_state;
1173
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001174 onu_key.onu_id = onu_id;
1175 onu_key.pon_ni = intf_id;
1176 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1177 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Girish Gowdra24297032020-03-23 12:32:37 -07001178#ifdef TEST_MODE
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001179 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1180 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1181 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1182 // of onu_cfg is passed. This is one-of case where we need to add test specific
1183 // code in production code.
1184 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Girish Gowdra24297032020-03-23 12:32:37 -07001185#else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001186 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Girish Gowdra24297032020-03-23 12:32:37 -07001187#endif
1188 OPENOLT_LOG(INFO, openolt_log_id, "Activate ONU : old state = %d, current state = %d\n",
1189 onu_cfg.data.onu_old_state, onu_cfg.data.onu_state);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001190 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001191 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) {
1192 OPENOLT_LOG(INFO, openolt_log_id, "ONU is already in ACTIVE state, \
1193not processing this request for pon_intf=%d onu_id=%d\n", intf_id, onu_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001194 return Status::OK;
Girish Gowdra24297032020-03-23 12:32:37 -07001195 } else if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_NOT_CONFIGURED &&
1196 onu_cfg.data.onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1197 // We need the ONU to be in NOT_CONFIGURED or INACTIVE state to further process the request
1198 OPENOLT_LOG(ERROR, openolt_log_id, "ONU in an invalid state to process the request, \
1199state=%d pon_intf=%d onu_id=%d\n", onu_cfg.data.onu_state, intf_id, onu_id);
1200 return bcm_to_grpc_err(err, "Failed to activate ONU, invalid ONU state");
1201 }
1202 } else {
1203 // This should never happen. BAL GET should succeed for non-existant ONUs too. The state of such ONUs will be NOT_CONFIGURED
1204 OPENOLT_LOG(ERROR, openolt_log_id, "ONU state query failed pon_intf=%d onu_id=%d\n", intf_id, onu_id);
1205 return bcm_to_grpc_err(err, "onu get failed");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001206 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001207
Girish Gowdra24297032020-03-23 12:32:37 -07001208 // If the ONU is not configured at all we need to first configure it
1209 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_NOT_CONFIGURED) {
1210 OPENOLT_LOG(INFO, openolt_log_id, "Configuring ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001211vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Girish Gowdra24297032020-03-23 12:32:37 -07001212 vendor_specific_to_str(vendor_specific).c_str(), pir);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001213
Girish Gowdra24297032020-03-23 12:32:37 -07001214 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1215 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1216 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1217 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1218 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1219 /*set burst and data profiles to fec disabled*/
1220 if (board_technology == "XGS-PON") {
1221 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1222 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1223 } else if (board_technology == "GPON") {
1224 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1225 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1226 }
1227 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1228 if (err != BCM_ERR_OK) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07001229 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 -07001230 return bcm_to_grpc_err(err, "Failed to configure ONU");
1231 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001232 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001233
Burak Gurdaga0523592021-02-24 15:17:47 +00001234// TODO: MOVE THIS TO A NEW METHOD
kesavandc1f2db92020-08-31 15:32:06 +05301235 if (omcc_encryption_mode == true) {
1236 // set the encryption mode for omci port id
1237 bcmolt_itupon_gem_cfg gem_cfg;
1238 bcmolt_itupon_gem_key key = {};
1239 bcmolt_gem_port_configuration configuration = {};
1240 key.pon_ni = intf_id;
1241 key.gem_port_id = onu_id;
1242 bcmolt_control_state encryption_mode;
1243 encryption_mode = BCMOLT_CONTROL_STATE_ENABLE;
1244 BCMOLT_CFG_INIT(&gem_cfg, itupon_gem, key);
1245 BCMOLT_FIELD_SET(&gem_cfg.data, itupon_gem_cfg_data, encryption_mode, encryption_mode);
1246 err = bcmolt_cfg_set(dev_id, &gem_cfg.hdr);
1247 if(err != BCM_ERR_OK) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07001248 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 +05301249 return bcm_to_grpc_err(err, "Access_Control set ITU PON OMCI Gem port failed");
1250 }
1251 }
Girish Gowdra24297032020-03-23 12:32:37 -07001252 // Now that the ONU is configured, move the ONU to ACTIVE state
1253 memset(&onu_cfg, 0, sizeof(bcmolt_onu_cfg));
1254 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1255 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1256 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
1257 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
1258 onu_state, BCMOLT_ONU_OPERATION_ACTIVE);
1259 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001260 if (err != BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001261 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 +00001262 return bcm_to_grpc_err(err, "Failed to activate ONU");
1263 }
Girish Gowdra24297032020-03-23 12:32:37 -07001264 // ONU will eventually get activated after we have submitted the operation request. The adapter will receive an asynchronous
1265 // ONU_ACTIVATION_COMPLETED_INDICATION
1266
1267 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 +00001268
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001269 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001270}
1271
Jonathan Davis70c21812018-07-19 15:32:10 -04001272Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1273 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001274 bcmos_errno err = BCM_ERR_OK;
1275 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1276 bcmolt_onu_cfg onu_cfg;
1277 bcmolt_onu_key onu_key; /**< Object key. */
1278 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001279
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001280 onu_key.onu_id = onu_id;
1281 onu_key.pon_ni = intf_id;
1282 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1283 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1284 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301285 onu_state = onu_cfg.data.onu_state;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001286 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001287 switch (onu_state) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001288 case BCMOLT_ONU_STATE_ACTIVE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001289 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001290 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001291 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1292 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1293 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001294 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 +00001295 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1296 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301297 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 +00001298 break;
1299 }
Girish Gowdra72cbee92021-11-05 15:16:18 -07001300 } else {
1301 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to deactivate ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
1302 return bcm_to_grpc_err(err, "Failed to get onu config");
Jonathan Davis70c21812018-07-19 15:32:10 -04001303 }
1304
1305 return Status::OK;
1306}
1307
1308Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001309 const char *vendor_id, const char *vendor_specific) {
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301310 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301311 bcmolt_onu_state onu_state;
Girish Gowdra72cbee92021-11-05 15:16:18 -07001312 Status st;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001313
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001314 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 -05001315 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1316
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001317 // Need to deactivate before removing it (BAL rules)
Girish Gowdra72cbee92021-11-05 15:16:18 -07001318 st = DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
1319 if (st.error_code() != grpc::StatusCode::OK) {
1320 return st;
1321 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301322
Girish Gowdra72cbee92021-11-05 15:16:18 -07001323 err = get_onu_state((bcmolt_interface)intf_id, onu_id, &onu_state);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301324 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001325 if (onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1326 OPENOLT_LOG(INFO, openolt_log_id, "waiting for onu deactivate complete response: intf_id=%d, onu_id=%d\n",
1327 intf_id, onu_id);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301328 err = wait_for_onu_deactivate_complete(intf_id, onu_id);
1329 if (err) {
1330 OPENOLT_LOG(ERROR, openolt_log_id, "failed to delete onu intf_id %d, onu_id %d\n",
1331 intf_id, onu_id);
1332 return bcm_to_grpc_err(err, "Failed to delete ONU");
1333 }
1334 }
Girish Gowdra24297032020-03-23 12:32:37 -07001335 else {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301336 OPENOLT_LOG(INFO, openolt_log_id, "Onu is Inactive, onu_id: %d, not waiting for onu deactivate complete response\n",
1337 intf_id);
1338 }
1339 }
1340 else {
1341 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch Onu status, onu_id = %d, intf_id = %d, err = %s\n",
1342 onu_id, intf_id, bcmos_strerror(err));
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301343 return bcm_to_grpc_err(err, "Failed to delete ONU");
1344 }
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001345
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001346 bcmolt_onu_cfg cfg_obj;
1347 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001348
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001349 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 -04001350 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001351
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001352 key.onu_id = onu_id;
1353 key.pon_ni = intf_id;
1354 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001355
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301356 err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001357 if (err != BCM_ERR_OK)
1358 {
Girish Gowdra72cbee92021-11-05 15:16:18 -07001359 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 -04001360 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1361 }
1362
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301363 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 +00001364 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001365}
1366
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001367#define MAX_CHAR_LENGTH 20
1368#define MAX_OMCI_MSG_LENGTH 44
1369Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001370 bcmolt_bin_str buf = {};
1371 bcmolt_onu_cpu_packets omci_cpu_packets;
1372 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001373
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001374 key.pon_ni = intf_id;
1375 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001376
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001377 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1378 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1379 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001380
1381 // ???
1382 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1383 buf.len = MAX_OMCI_MSG_LENGTH;
1384 } else {
1385 buf.len = pkt.size()/2;
1386 }
1387
1388 /* Send the OMCI packet using the BAL remote proxy API */
1389 uint16_t idx1 = 0;
1390 uint16_t idx2 = 0;
1391 uint8_t arraySend[buf.len];
1392 char str1[MAX_CHAR_LENGTH];
1393 char str2[MAX_CHAR_LENGTH];
1394 memset(&arraySend, 0, buf.len);
1395
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001396 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1397 sprintf(str1,"%c", pkt[idx1]);
1398 sprintf(str2,"%c", pkt[++idx1]);
1399 strcat(str1,str2);
1400 arraySend[idx2] = strtol(str1, NULL, 16);
1401 }
1402
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001403 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1404 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001405
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001406 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1407 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1408 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001409
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001410 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001411 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001412 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 +00001413 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001414 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001415 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 -05001416 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001417 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001418 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001419
1420 return Status::OK;
1421}
1422
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001423Status 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 +00001424 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1425 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1426 bcmolt_bin_str buf = {};
1427 bcmolt_gem_port_id gem_port_id_array[1];
1428 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001429
Craig Lutgen967a1d02018-11-27 10:41:51 -06001430 if (port_no > 0) {
1431 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001432 if (gemport_id == 0) {
1433 bcmos_fastlock_lock(&data_lock);
1434 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1435 // Pick any flow that is mapped with the same port_no.
1436 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1437 if (it != port_to_flows.end() && !it->second.empty()) {
1438 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1439 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1440 if (fit != flowid_to_gemport.end()) {
1441 found = true;
1442 gemport_id = fit->second;
1443 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001444 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001445 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001446
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001447 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001448 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 -08001449 onu_id, port_no, intf_id);
1450 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1451 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001452 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 -08001453 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001454 }
1455
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001456 gem_port_id_array[0] = gemport_id;
1457 gem_port_list.len = 1;
1458 gem_port_list.arr = gem_port_id_array;
1459 buf.len = pkt.size();
1460 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1461 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1462
1463 /* init the API struct */
1464 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1465 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1466 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1467 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1468 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1469
1470 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1471 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1472
1473 /* call API */
1474 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001475 }
1476 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001477 //TODO: Port No is 0, it is coming sender requirement.
1478 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1479 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001480 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001481 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001482
1483 return Status::OK;
1484}
1485
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001486Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001487 bcmolt_flow_key key = {}; /* declare key */
1488 bcmolt_bin_str buffer = {};
1489 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001490
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001491 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
Girish Gowdra252f4972020-09-07 21:24:01 -07001492 bcmolt_flow_id flow_id = INVALID_FLOW_ID;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001493
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001494 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1495 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1496 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1497 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1498 key.flow_id = flow_id;
1499 else {
Jason Huang09b73ea2020-01-08 17:52:05 +08001500 if (flow_id_counters) {
1501 std::map<flow_pair, int>::iterator it;
1502 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1503 int flow_index = it->first.first;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001504 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1505 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1506 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1507 key.flow_id = flow_index;
1508 break;
1509 }
1510 }
1511 }
1512 else {
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001513 OPENOLT_LOG(ERROR, openolt_log_id, "no flow id found for uplink packetout\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001514 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1515 }
1516 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001517
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001518 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001519
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001520 /* Initialize the API struct. */
1521 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001522
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001523 buffer.len = pkt.size();
1524 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1525 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1526 if (buffer.arr == NULL) {
1527 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1528 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1529 }
1530 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1531
1532 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1533 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001534 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 -05001535 return bcm_to_grpc_err(BCM_ERR_SYSCALL_ERR, "Error sending packets via nni port");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001536 } else {
1537 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1538 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001539
1540 return Status::OK;
1541}
Girish Gowdra252f4972020-09-07 21:24:01 -07001542
Burak Gurdaga0523592021-02-24 15:17:47 +00001543bool get_aes_flag_for_gem_port(const google::protobuf::Map<unsigned int, bool> &gemport_to_aes, uint32_t gemport_id) {
1544 bool aes_flag = false;
1545 for (google::protobuf::Map<unsigned int, bool>::const_iterator it=gemport_to_aes.begin(); it!=gemport_to_aes.end(); it++) {
1546 if (it->first == gemport_id) {
1547 aes_flag = it->second;
1548 break;
1549 }
1550 }
1551 return aes_flag;
1552}
1553
Girish Gowdra252f4972020-09-07 21:24:01 -07001554Status FlowAddWrapper_(const ::openolt::Flow* request) {
1555
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001556 Status st = Status::OK;
Girish Gowdra252f4972020-09-07 21:24:01 -07001557 int32_t access_intf_id = request->access_intf_id();
1558 int32_t onu_id = request->onu_id();
1559 int32_t uni_id = request->uni_id();
1560 uint32_t port_no = request->port_no();
1561 uint64_t voltha_flow_id = request->flow_id();
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001562 uint64_t symmetric_voltha_flow_id = 0;
Girish Gowdra252f4972020-09-07 21:24:01 -07001563 const std::string flow_type = request->flow_type();
1564 int32_t alloc_id = request->alloc_id();
1565 int32_t network_intf_id = request->network_intf_id();
1566 int32_t gemport_id = request->gemport_id();
1567 const ::openolt::Classifier& classifier = request->classifier();
1568 const ::openolt::Action& action = request->action();
1569 int32_t priority = request->priority();
1570 uint64_t cookie = request->cookie();
1571 int32_t group_id = request->group_id();
1572 uint32_t tech_profile_id = request->tech_profile_id();
1573 bool replicate_flow = request->replicate_flow();
1574 const google::protobuf::Map<unsigned int, unsigned int> &pbit_to_gemport = request->pbit_to_gemport();
Burak Gurdaga0523592021-02-24 15:17:47 +00001575 const google::protobuf::Map<unsigned int, bool> &gemport_to_aes = request->gemport_to_aes();
Girish Gowdra252f4972020-09-07 21:24:01 -07001576 uint16_t flow_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001577 bool enable_encryption;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001578 // When following conditions are ALL met, it qualifies as datapath flow.
1579 // 1. valid access_intf_id, onu_id, uni_id
1580 // 2. Valid tech_profile_id
1581 // 3. flow_type that is not MULTICAST
1582 // 4. Not a trap-to-host flow.
1583 bool datapathFlow = access_intf_id >= 0 && onu_id >= 0 && uni_id >= 0 && tech_profile_id > 0
1584 && flow_type != multicast && !action.cmd().trap_to_host();
1585
1586 if (datapathFlow) {
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08001587 const std::string inverse_flow_type = flow_type == upstream? downstream : upstream;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001588 symmetric_datapath_flow_id_map_key key(access_intf_id, onu_id, uni_id, tech_profile_id, inverse_flow_type);
1589 // Find the onu-uni mapping for the pon-gem key
1590 bcmos_fastlock_lock(&symmetric_datapath_flow_id_lock);
1591 auto it = symmetric_datapath_flow_id_map.find(key);
1592 bcmos_fastlock_unlock(&symmetric_datapath_flow_id_lock, 0);
1593 if (it != symmetric_datapath_flow_id_map.end()) {
1594 symmetric_voltha_flow_id = it->second;
1595 }
1596 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001597
1598 // The intf_id variable defaults to access(PON) interface ID.
1599 // For trap-from-nni flow where access interface ID is not valid , change it to NNI interface ID
1600 // This intf_id identifies the pool from which we get the flow_id
1601 uint32_t intf_id = access_intf_id;
1602 if (onu_id < 1) {
1603 onu_id = 1;
1604 }
1605 if (access_intf_id < 0) {
1606 intf_id = network_intf_id;
1607 }
1608
1609 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)
1610 // This is the case of voltha_flow_id (not symmetric_voltha_flow_id)
1611 if (is_voltha_flow_installed(voltha_flow_id)) {
1612 OPENOLT_LOG(INFO, openolt_log_id, "voltha_flow_id=%lu, already installed\n", voltha_flow_id);
1613 return ::Status(grpc::StatusCode::ALREADY_EXISTS, "voltha-flow-already-installed");
1614 }
1615
Girish Gowdra252f4972020-09-07 21:24:01 -07001616 // This is the case of symmetric_voltha_flow_id
1617 // If symmetric_voltha_flow_id is available and valid in the Flow message,
1618 // check if it is installed, and use the corresponding device_flow_id
1619 if (symmetric_voltha_flow_id > 0 && is_voltha_flow_installed(symmetric_voltha_flow_id)) { // symmetric flow found
1620 OPENOLT_LOG(INFO, openolt_log_id, "symmetric flow and the symmetric flow is installed\n");
1621 const device_flow_params *dev_fl_symm_params;
1622 dev_fl_symm_params = get_device_flow_params(symmetric_voltha_flow_id);
1623 if (dev_fl_symm_params == NULL) {
1624 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)
1625 return ::Status(grpc::StatusCode::INTERNAL, "symmetric-flow-details-not-found");
1626 }
1627
1628 if (!replicate_flow) { // No flow replication
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001629 flow_id = dev_fl_symm_params[0].flow_id;
1630 gemport_id = dev_fl_symm_params[0].gemport_id; // overwrite the gemport with symmetric flow gemport
1631 // Should be same as what is coming in this request.
1632 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
1633 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1634 cl.set_o_pbits(dev_fl_symm_params[0].pbit);
1635 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1636 flow_type, alloc_id, network_intf_id, gemport_id, cl,
1637 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
1638 if (st.error_code() != grpc::StatusCode::OK && st.error_code() != grpc::StatusCode::ALREADY_EXISTS) {
1639 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 -07001640 free_flow_id(flow_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001641 return st;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001642 }
1643
1644 device_flow dev_fl;
1645 dev_fl.is_flow_replicated = false;
1646 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1647 dev_fl.voltha_flow_id = voltha_flow_id;
Girish Gowdra72bb4652022-01-18 17:04:30 -08001648 dev_fl.flow_type = flow_type;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001649 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params));
1650 // update voltha flow to cache
1651 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
Girish Gowdra252f4972020-09-07 21:24:01 -07001652 } else { // Flow to be replicated
1653 OPENOLT_LOG(INFO, openolt_log_id,"symmetric flow and replication is needed\n");
1654 for (uint8_t i=0; i<NUMBER_OF_REPLICATED_FLOWS; i++) {
1655 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1656 flow_id = dev_fl_symm_params[i].flow_id;
1657 gemport_id = dev_fl_symm_params[i].gemport_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001658 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001659 cl.set_o_pbits(dev_fl_symm_params[i].pbit);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001660 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdrade65ab42020-12-17 23:08:43 -08001661 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001662 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001663 if (st.error_code() != grpc::StatusCode::OK && st.error_code() != grpc::StatusCode::ALREADY_EXISTS) {
1664 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);
1665 // On failure remove any successfully replicated flows installed so far for the voltha_flow_id
1666 if (i > 0) {
1667 for (int8_t j = i-1; j >= 0; j--) {
1668 flow_id = dev_fl_symm_params[j].flow_id;
1669 FlowRemove_(flow_id, flow_type);
1670 }
1671 }
Girish Gowdra72cbee92021-11-05 15:16:18 -07001672 // Note: We should not free the flow_ids here because the symmetric flow is already using that flow id.
1673 // 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 -07001674 return st;
1675 }
1676 }
1677 device_flow dev_fl;
1678 dev_fl.is_flow_replicated = true;
1679 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1680 dev_fl.voltha_flow_id = voltha_flow_id;
Girish Gowdra72bb4652022-01-18 17:04:30 -08001681 dev_fl.flow_type = flow_type;
Girish Gowdra252f4972020-09-07 21:24:01 -07001682 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params)*NUMBER_OF_REPLICATED_FLOWS);
1683 // update voltha flow to cache
1684 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1685 }
1686 } else { // No symmetric flow found
1687 if (!replicate_flow) { // No flow replication
1688 OPENOLT_LOG(INFO, openolt_log_id, "not a symmetric flow and replication is not needed\n");
1689 flow_id = get_flow_id();
1690 if (flow_id == INVALID_FLOW_ID) {
1691 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocated flow id for voltha-flow-id=%lu\n", voltha_flow_id);
1692 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1693 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001694 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001695 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001696 flow_type, alloc_id, network_intf_id, gemport_id, classifier,
Burak Gurdaga0523592021-02-24 15:17:47 +00001697 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001698 if (st.error_code() == grpc::StatusCode::OK) {
1699 device_flow dev_fl;
1700 dev_fl.is_flow_replicated = false;
1701 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // Invalid
1702 dev_fl.voltha_flow_id = voltha_flow_id;
Girish Gowdra72bb4652022-01-18 17:04:30 -08001703 dev_fl.flow_type = flow_type;
Girish Gowdra252f4972020-09-07 21:24:01 -07001704 dev_fl.params[0].flow_id = flow_id;
1705 dev_fl.params[0].gemport_id = gemport_id;
1706 dev_fl.params[0].pbit = classifier.o_pbits();
1707 // update voltha flow to cache
1708 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1709 } else {
1710 // Free the flow id on failure
1711 free_flow_id(flow_id);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001712 return st;
Girish Gowdra252f4972020-09-07 21:24:01 -07001713 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001714 } else { // Flow to be replicated
1715 OPENOLT_LOG(INFO, openolt_log_id,"not a symmetric flow and replication is needed\n");
1716 if (pbit_to_gemport.size() != NUMBER_OF_PBITS) {
1717 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pbit-to-gemport map size=%lu", pbit_to_gemport.size())
1718 return ::Status(grpc::StatusCode::OUT_OF_RANGE, "pbit-to-gemport-map-len-invalid-for-flow-replication");
1719 }
1720 uint16_t flow_ids[NUMBER_OF_REPLICATED_FLOWS];
1721 device_flow dev_fl;
1722 if (get_flow_ids(NUMBER_OF_REPLICATED_FLOWS, flow_ids)) {
1723 uint8_t cnt = 0;
1724 dev_fl.is_flow_replicated = true;
1725 dev_fl.voltha_flow_id = voltha_flow_id;
1726 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // invalid
Girish Gowdra72bb4652022-01-18 17:04:30 -08001727 dev_fl.flow_type = flow_type;
Girish Gowdra252f4972020-09-07 21:24:01 -07001728 for (google::protobuf::Map<unsigned int, unsigned int>::const_iterator it=pbit_to_gemport.begin(); it!=pbit_to_gemport.end(); it++) {
1729 dev_fl.params[cnt].flow_id = flow_ids[cnt];
1730 dev_fl.params[cnt].pbit = it->first;
1731 dev_fl.params[cnt].gemport_id = it->second;
1732
1733 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1734 flow_id = dev_fl.params[cnt].flow_id;
1735 gemport_id = dev_fl.params[cnt].gemport_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001736 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001737 cl.set_o_pbits(dev_fl.params[cnt].pbit);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001738 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001739 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001740 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001741 if (st.error_code() != grpc::StatusCode::OK) {
1742 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);
1743 // Remove any successfully replicated flows installed so far for the voltha_flow_id
1744 if (cnt > 0) {
1745 for (int8_t j = cnt-1; j >= 0; j--) {
1746 flow_id = dev_fl.params[j].flow_id;
1747 FlowRemove_(flow_id, flow_type);
1748 }
1749 }
1750 // Free up all the flow IDs on failure
1751 free_flow_ids(NUMBER_OF_REPLICATED_FLOWS, flow_ids);
1752 return st;
1753 }
1754 cnt++;
1755 }
1756 // On successful flow replication update voltha-flow-id to device-flow map to cache
1757 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1758 } else {
1759 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocate flow ids for replication voltha-flow-id=%lu\n", voltha_flow_id);
1760 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1761 }
1762 }
1763 }
1764
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001765 if (datapathFlow) {
1766 // Create the pon-gem to onu-uni mapping
1767 symmetric_datapath_flow_id_map_key key(access_intf_id, onu_id, uni_id, tech_profile_id, flow_type);
1768 bcmos_fastlock_lock(&symmetric_datapath_flow_id_lock);
1769 symmetric_datapath_flow_id_map[key] = voltha_flow_id;
1770 bcmos_fastlock_unlock(&symmetric_datapath_flow_id_lock, 0);
1771 }
1772
1773 return st;
Girish Gowdra252f4972020-09-07 21:24:01 -07001774}
1775
1776
Craig Lutgen967a1d02018-11-27 10:41:51 -06001777Status 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 +00001778 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001779 int32_t alloc_id, int32_t network_intf_id,
1780 int32_t gemport_id, const ::openolt::Classifier& classifier,
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001781 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie,
Burak Gurdaga0523592021-02-24 15:17:47 +00001782 int32_t group_id, uint32_t tech_profile_id, bool aes_enabled) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001783 bcmolt_flow_cfg cfg;
1784 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001785 int32_t o_vid = -1;
1786 bool single_tag = false;
1787 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001788 bcmolt_classifier c_val = { };
1789 bcmolt_action a_val = { };
1790 bcmolt_tm_queue_ref tm_val = { };
1791 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05001792 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001793
Jason Huang09b73ea2020-01-08 17:52:05 +08001794 OPENOLT_LOG(INFO, openolt_log_id, "flow add received for flow_id=%u, flow_type=%s\n", flow_id, flow_type.c_str());
1795
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001796 key.flow_id = flow_id;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08001797 if (flow_type == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001798 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08001799 } else if (flow_type == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001800 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08001801 } else if (flow_type == multicast) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001802 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001803 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001804 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001805 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001806 }
1807
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001808 BCMOLT_CFG_INIT(&cfg, flow, key);
1809 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001810
Jason Huang09b73ea2020-01-08 17:52:05 +08001811 if (action.cmd().trap_to_host()) {
Girish Gowdra1935e6a2020-10-31 21:48:22 -07001812 Status resp = handle_acl_rule_install(onu_id, flow_id, gemport_id, flow_type, access_intf_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001813 network_intf_id, classifier);
Jason Huang09b73ea2020-01-08 17:52:05 +08001814 return resp;
1815 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001816
1817 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1818
1819 if (access_intf_id >= 0 && network_intf_id >= 0) {
1820 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1821 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1822 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08001823 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1824 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001825 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1826 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1827 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1828 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1829 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001830 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001831 } else {
1832 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
1833 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001834 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001835
Burak Gurdaga0523592021-02-24 15:17:47 +00001836 if (onu_id >= ONU_ID_START) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001837 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
1838 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001839 if (gemport_id >= GEM_PORT_ID_START) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001840 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
1841 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001842 if (gemport_id >= GEM_PORT_ID_START && port_no != 0) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001843 bcmos_fastlock_lock(&data_lock);
1844 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
1845 port_to_flows[port_no].insert(key.flow_id);
1846 flowid_to_gemport[key.flow_id] = gemport_id;
1847 }
1848 else
1849 {
1850 flowid_to_port[key.flow_id] = port_no;
1851 }
1852 bcmos_fastlock_unlock(&data_lock, 0);
1853 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001854
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001855 if (priority_value >= 0) {
1856 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
1857 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301858
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001859 } else { // MULTICAST FLOW
1860 if (group_id >= 0) {
1861 BCMOLT_MSG_FIELD_SET(&cfg, group_id, group_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001862 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001863 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1864 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001865 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001866
1867 {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001868 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001869 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001870 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
1871 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001872 }
1873
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001874 if (classifier.dst_mac().size() > 0) {
1875 bcmos_mac_address d_mac = {};
1876 bcmos_mac_address_init(&d_mac);
1877 memcpy(d_mac.u8, classifier.dst_mac().data(), sizeof(d_mac.u8));
1878 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_mac %02x:%02x:%02x:%02x:%02x:%02x\n", d_mac.u8[0],
1879 d_mac.u8[1], d_mac.u8[2], d_mac.u8[3], d_mac.u8[4], d_mac.u8[5]);
1880 BCMOLT_FIELD_SET(&c_val, classifier, dst_mac, d_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001881 }
1882
Girish Gowdraf83e17a2022-02-16 16:27:00 -08001883 if (classifier.src_mac().size() > 0) {
1884 bcmos_mac_address s_mac = {};
1885 bcmos_mac_address_init(&s_mac);
1886 memcpy(s_mac.u8, classifier.src_mac().data(), sizeof(s_mac.u8));
1887 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_mac %02x:%02x:%02x:%02x:%02x:%02x\n", s_mac.u8[0],
1888 s_mac.u8[1], s_mac.u8[2], s_mac.u8[3], s_mac.u8[4], s_mac.u8[5]);
1889 BCMOLT_FIELD_SET(&c_val, classifier, src_mac, s_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001890 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001891
1892 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001893 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
1894 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001895 }
1896
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001897 if (classifier.dst_ip()) {
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08001898 bcmos_ipv4_address d_ip = {};
1899 bcmos_ipv4_address_init(&d_ip);
1900 d_ip.u32 = classifier.dst_ip();
1901 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_ip %04x\n", d_ip.u32);
1902 BCMOLT_FIELD_SET(&c_val, classifier, dst_ip, d_ip);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001903 }
1904
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08001905 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001906 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001907 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001908 }
1909 */
1910
1911 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001912 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
1913 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001914 }
1915
1916 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001917 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
1918 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001919 }
1920
1921 if (!classifier.pkt_tag_type().empty()) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001922 if (classifier.o_vid()) {
1923 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
1924 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
1925 }
1926
1927 if (classifier.i_vid()) {
1928 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
1929 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
1930 }
1931
1932 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
1933 if (classifier.pkt_tag_type().compare("untagged") == 0) {
1934 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
1935 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
1936 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
1937 single_tag = true;
1938
1939 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301940 // OpenOlt adapter will send 0xFF in case of no pbit classification
1941 // If it is any other value (0 to 7), it is for outer pbit classification.
1942 // OpenFlow protocol does not provide inner pbit classification (in case of double tagged packets),
1943 // and VOLTHA has not used any workaround to solve this problem (for ex: use metadata field).
1944 // Also there exists no use case for i-pbit classification, so we can safely ignore this for now.
1945 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001946 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301947 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001948 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
1949 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001950
Jason Huang09b73ea2020-01-08 17:52:05 +08001951 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301952 // Same comments as in case of "single_tag" packets.
1953 // 0xFF means no pbit classification, otherwise a valid PCP (0 to 7).
1954 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001955 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301956 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001957 }
1958 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001959 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001960 }
1961
Jason Huang09b73ea2020-01-08 17:52:05 +08001962 const ::openolt::ActionCmd& cmd = action.cmd();
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001963
Jason Huang09b73ea2020-01-08 17:52:05 +08001964 if (cmd.add_outer_tag()) {
1965 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
1966 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001967 }
1968
Jason Huang09b73ea2020-01-08 17:52:05 +08001969 if (cmd.remove_outer_tag()) {
1970 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
1971 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
1972 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301973
Girish Gowdraf83e17a2022-02-16 16:27:00 -08001974 if (cmd.translate_outer_tag()) {
1975 OPENOLT_LOG(DEBUG, openolt_log_id, "action translate o_tag\n");
1976 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_XLATE_OUTER_TAG);
1977 }
1978
Jason Huang09b73ea2020-01-08 17:52:05 +08001979 if (action.o_vid()) {
1980 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
1981 o_vid = action.o_vid();
1982 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
1983 }
1984
1985 if (action.o_pbits()) {
1986 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
1987 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
1988 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301989
Jason Huang09b73ea2020-01-08 17:52:05 +08001990 if (action.i_vid()) {
1991 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
1992 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
1993 }
1994
1995 if (action.i_pbits()) {
1996 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
1997 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
1998 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301999
Jason Huang09b73ea2020-01-08 17:52:05 +08002000 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
2001
Burak Gurdaga0523592021-02-24 15:17:47 +00002002 if ((access_intf_id >= 0) && (onu_id >= ONU_ID_START)) {
Jason Huang09b73ea2020-01-08 17:52:05 +08002003 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
2004 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002005 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 +00002006
Jason Huang09b73ea2020-01-08 17:52:05 +08002007 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2008 // Queue 0 on DS subscriber scheduler
2009 tm_val.queue_id = 0;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002010
Jason Huang09b73ea2020-01-08 17:52:05 +08002011 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2012 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2013 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002014
Jason Huang09b73ea2020-01-08 17:52:05 +08002015 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2016 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2017 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002018
Jason Huang09b73ea2020-01-08 17:52:05 +08002019 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2020 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
2021 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 +00002022
Jason Huang09b73ea2020-01-08 17:52:05 +08002023 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2024 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2025 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2026 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 +00002027
Jason Huang09b73ea2020-01-08 17:52:05 +08002028 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2029 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2030 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2031 }
2032 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
2033 // NNI Scheduler ID
2034 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2035 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2036 // Queue 0 on NNI scheduler
2037 tm_val.queue_id = 0;
2038 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2039 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2040 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002041
Jason Huang09b73ea2020-01-08 17:52:05 +08002042 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002043 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2044 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2045
Jason Huang09b73ea2020-01-08 17:52:05 +08002046 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2047 /* Fetch TM QMP ID mapped to US NNI scheduler */
2048 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2049 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2050 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2051 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2052 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 +00002053
Jason Huang09b73ea2020-01-08 17:52:05 +08002054 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 +00002055 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2056 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002057 }
Shad Ansari39739bc2018-09-13 21:38:37 +00002058 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302059 } else {
2060 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2061 tm_val.queue_id = 0;
2062
2063 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2064 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2065 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2066
2067 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2068 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
2069 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00002070 }
2071
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002072 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002073
Girish Gowdra252f4972020-09-07 21:24:01 -07002074#ifndef SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002075 // BAL 3.1 supports statistics only for unicast flows.
2076 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
2077 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
2078 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002079#endif // SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002080
Girish Gowdra252f4972020-09-07 21:24:01 -07002081#ifndef SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002082#ifdef FLOW_CHECKER
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002083 //Flow Checker, To avoid duplicate flow.
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002084 if (flow_id_counters != 0) {
2085 bool b_duplicate_flow = false;
Jason Huang09b73ea2020-01-08 17:52:05 +08002086 std::map<flow_pair, int>::iterator it;
2087
2088 for(it = flow_map.begin(); it != flow_map.end(); it++) {
2089 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(it->first.first, it->first.second, ONU_ID)) && \
2090 (key.flow_type == it->first.second) && \
2091 (cfg.data.svc_port_id == get_flow_status(it->first.first, it->first.second, SVC_PORT_ID)) && \
2092 (cfg.data.priority == get_flow_status(it->first.first, it->first.second, PRIORITY)) && \
2093 (cfg.data.cookie == get_flow_status(it->first.first, it->first.second, COOKIE)) && \
2094 (cfg.data.ingress_intf.intf_type == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_TYPE)) && \
2095 (cfg.data.ingress_intf.intf_id == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_ID)) && \
2096 (cfg.data.egress_intf.intf_type == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_TYPE)) && \
2097 (cfg.data.egress_intf.intf_id == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_ID)) && \
2098 (c_val.o_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_VID)) && \
2099 (c_val.o_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_PBITS)) && \
2100 (c_val.i_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_VID)) && \
2101 (c_val.i_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_PBITS)) && \
2102 (c_val.ether_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_ETHER_TYPE)) && \
2103 (c_val.ip_proto == get_flow_status(it->first.first, it->first.second, CLASSIFIER_IP_PROTO)) && \
2104 (c_val.src_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_SRC_PORT)) && \
2105 (c_val.dst_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_DST_PORT)) && \
2106 (c_val.pkt_tag_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_PKT_TAG_TYPE)) && \
2107 (cfg.data.egress_qos.type == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TYPE)) && \
2108 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_QUEUE_ID)) && \
2109 (cfg.data.egress_qos.tm_sched.id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TM_SCHED_ID)) && \
2110 (a_val.cmds_bitmask == get_flow_status(it->first.first, it->first.second, ACTION_CMDS_BITMASK)) && \
2111 (a_val.o_vid == get_flow_status(it->first.first, it->first.second, ACTION_O_VID)) && \
2112 (a_val.i_vid == get_flow_status(it->first.first, it->first.second, ACTION_I_VID)) && \
2113 (a_val.o_pbits == get_flow_status(it->first.first, it->first.second, ACTION_O_PBITS)) && \
2114 (a_val.i_pbits == get_flow_status(it->first.first, it->first.second, ACTION_I_PBITS)) && \
2115 (cfg.data.state == get_flow_status(it->first.first, it->first.second, STATE)) && \
2116 (cfg.data.group_id == get_flow_status(it->first.first, it->first.second, GROUP_ID));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002117#ifdef SHOW_FLOW_PARAM
2118 // Flow Parameter
2119 FLOW_PARAM_LOG();
2120#endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002121 if (b_duplicate_flow) {
2122 FLOW_LOG(WARNING, "Flow duplicate", 0);
2123 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
2124 }
2125 }
2126 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002127#endif // FLOW_CHECKER
2128#endif // SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002129
2130 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2131 if (err) {
2132 FLOW_LOG(ERROR, "Flow add failed", err);
2133 return bcm_to_grpc_err(err, "flow add failed");
2134 } else {
2135 FLOW_LOG(INFO, "Flow add ok", err);
2136 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002137 flow_map[std::pair<int, int>(key.flow_id,key.flow_type)] = flow_map.size();
2138 flow_id_counters = flow_map.size();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002139 bcmos_fastlock_unlock(&data_lock, 0);
Girish Gowdra252f4972020-09-07 21:24:01 -07002140
2141 }
Burak Gurdaga0523592021-02-24 15:17:47 +00002142
2143 /*
2144 Enable AES encryption on GEM ports if they are used in downstream unicast flows.
2145 Rationale: We can't do upstream encryption in GPON. This change addresses the common denominator (and also minimum viable)
2146 use case for both technologies which is downstream unicast GEM port encryption. Since the downstream traffic is inherently
2147 broadcast to all the ONUs behind a PON port, encrypting the individual subscriber traffic in this direction is important
2148 and considered good enough in terms of security (See Section 12.1 of G.984.3). For upstream unicast and downstream multicast
2149 GEM encryption, we need to make additional changes specific to XGSPON. This will be done as a future work.
2150 */
2151 if (aes_enabled && (access_intf_id >= 0) && (gemport_id >= GEM_PORT_ID_START) && (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM)) {
2152 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 +05302153 enable_encryption_for_gem_port(access_intf_id, gemport_id, board_technology);
Burak Gurdaga0523592021-02-24 15:17:47 +00002154 } else {
2155 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);
2156 }
2157
Girish Gowdra252f4972020-09-07 21:24:01 -07002158 return Status::OK;
2159}
2160
2161Status FlowRemoveWrapper_(const ::openolt::Flow* request) {
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002162 int32_t access_intf_id = request->access_intf_id();
2163 int32_t onu_id = request->onu_id();
2164 int32_t uni_id = request->uni_id();
2165 uint32_t tech_profile_id = request->tech_profile_id();
Girish Gowdra252f4972020-09-07 21:24:01 -07002166 uint64_t voltha_flow_id = request->flow_id();
2167 Status st;
2168
2169 // If Voltha flow is not installed, return fail
2170 if (! is_voltha_flow_installed(voltha_flow_id)) {
2171 OPENOLT_LOG(ERROR, openolt_log_id, "voltha_flow_id=%lu not found\n", voltha_flow_id);
2172 return ::Status(grpc::StatusCode::NOT_FOUND, "voltha-flow-not-found");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002173 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04002174
Girish Gowdra252f4972020-09-07 21:24:01 -07002175 const device_flow *dev_fl = get_device_flow(voltha_flow_id);
2176 if (dev_fl == NULL) {
2177 OPENOLT_LOG(ERROR, openolt_log_id, "device flow for voltha_flow_id=%lu in the cache is NULL\n", voltha_flow_id);
2178 return ::Status(grpc::StatusCode::INTERNAL, "device-flow-null-in-cache");
2179 }
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002180 std::string flow_type = dev_fl->flow_type;
Girish Gowdra252f4972020-09-07 21:24:01 -07002181 if (dev_fl->is_flow_replicated) {
2182 // Note: Here we are ignoring FlowRemove failures
2183 for (int i=0; i<NUMBER_OF_REPLICATED_FLOWS; i++) {
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002184 st = FlowRemove_(dev_fl->params[i].flow_id, flow_type);
Girish Gowdra252f4972020-09-07 21:24:01 -07002185 if (st.error_code() == grpc::StatusCode::OK) {
2186 free_flow_id(dev_fl->params[i].flow_id);
2187 }
2188 }
2189 } else {
2190 // Note: Here we are ignoring FlowRemove failures
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002191 st = FlowRemove_(dev_fl->params[0].flow_id, flow_type);
Girish Gowdra252f4972020-09-07 21:24:01 -07002192 if (st.error_code() == grpc::StatusCode::OK) {
2193 free_flow_id(dev_fl->params[0].flow_id);
2194 }
2195 }
2196 // remove the flow from cache on voltha flow removal
2197 remove_voltha_flow_from_cache(voltha_flow_id);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002198
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002199 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 -07002200 // Remove onu-uni mapping for the pon-gem key
2201 bcmos_fastlock_lock(&symmetric_datapath_flow_id_lock);
2202 symmetric_datapath_flow_id_map.erase(key);
2203 bcmos_fastlock_unlock(&symmetric_datapath_flow_id_lock, 0);
2204
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002205 return Status::OK;
2206}
2207
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002208Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
2209
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002210 bcmolt_flow_cfg cfg;
2211 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002212
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002213 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002214 key.flow_id = flow_id;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002215 if (flow_type == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002216 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002217 } else if (flow_type == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002218 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002219 } else if(flow_type == multicast) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002220 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002221 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002222 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002223 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
2224 }
2225
Jason Huang09b73ea2020-01-08 17:52:05 +08002226 OPENOLT_LOG(INFO, openolt_log_id, "flow remove received for flow_id=%u, flow_type=%s\n",
2227 flow_id, flow_type.c_str());
2228
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002229 bcmos_fastlock_lock(&acl_packet_trap_handler_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002230 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
2231 int32_t gemport_id = -1;
2232 int32_t intf_id = -1;
2233 int16_t acl_id = -1;
2234 if (flow_to_acl_map.count(fl_id_fl_dir) > 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002235
2236 acl_id_intf_id ac_id_if_id = flow_to_acl_map[fl_id_fl_dir];
2237 acl_id = std::get<0>(ac_id_if_id);
2238 intf_id = std::get<1>(ac_id_if_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002239 // cleanup acl only if it is a valid acl. If not valid acl, it may be datapath flow.
2240 if (acl_id >= 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002241 Status resp = handle_acl_rule_cleanup(acl_id, intf_id, flow_type);
Jason Huang09b73ea2020-01-08 17:52:05 +08002242 if (resp.ok()) {
2243 OPENOLT_LOG(INFO, openolt_log_id, "acl removed ok for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2244 flow_to_acl_map.erase(fl_id_fl_dir);
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002245
2246 // 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
2247 if (trap_to_host_pkt_info_with_vlan_for_flow_id.count(flow_id) > 0) {
2248 trap_to_host_pkt_info_with_vlan pkt_info_with_vlan = trap_to_host_pkt_info_with_vlan_for_flow_id[flow_id];
2249 // Formulate the trap_to_host_pkt_info tuple key
2250 trap_to_host_pkt_info pkt_info(std::get<0>(pkt_info_with_vlan),
2251 std::get<1>(pkt_info_with_vlan),
2252 std::get<2>(pkt_info_with_vlan),
2253 std::get<3>(pkt_info_with_vlan));
2254 // Extract the value corresponding to trap_to_host_pkt_info key from trap_to_host_vlan_ids_for_trap_to_host_pkt_info
2255 // The value is a list of vlan_ids for the given trap_to_host_pkt_info key
2256 // Remove the vlan_id from the list that corresponded to the flow being removed.
2257 if (trap_to_host_vlan_ids_for_trap_to_host_pkt_info.count(pkt_info) > 0) {
2258 trap_to_host_vlan_ids_for_trap_to_host_pkt_info[pkt_info].remove(std::get<4>(pkt_info_with_vlan));
2259 } else {
2260 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",
2261 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));
2262 }
2263
2264 } else {
2265 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);
2266 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002267 } else {
2268 OPENOLT_LOG(ERROR, openolt_log_id, "acl remove error for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2269 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002270 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002271 return resp;
2272 }
2273 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002274 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002275
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002276 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002277 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002278 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002279 flowid_to_gemport.erase(key.flow_id);
2280 port_to_flows[port_no].erase(key.flow_id);
2281 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
2282 }
2283 else
2284 {
2285 flowid_to_port.erase(key.flow_id);
2286 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002287 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002288
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002289 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002290
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002291 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002292 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07002293 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 -04002294 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
2295 }
2296
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002297 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002298 if (flow_id_counters != 0) {
2299 std::map<flow_pair, int>::iterator it;
2300 for(it = flow_map.begin(); it != flow_map.end(); it++) {
2301 if (it->first.first == flow_id && it->first.second == key.flow_type) {
2302 flow_id_counters -= 1;
2303 flow_map.erase(it);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002304 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002305 }
2306 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002307 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
2308
Jason Huang09b73ea2020-01-08 17:52:05 +08002309 flow_to_acl_map.erase(fl_id_fl_dir);
2310
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002311 bcmos_fastlock_unlock(&data_lock, 0);
2312
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002313 return Status::OK;
2314}
2315
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002316bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
2317 bcmos_errno err;
2318 bcmolt_tm_sched_cfg tm_sched_cfg;
2319 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2320 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
2321
Jason Huangbf45ffb2019-10-30 17:29:02 +08002322 //check TM scheduler has configured or not
2323 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2324 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002325 #ifdef TEST_MODE
2326 // It is impossible to mock the setting of tm_sched_cfg.data.state because
2327 // the actual bcmolt_cfg_get passes the address of tm_sched_cfg.hdr and we cannot
2328 // set the tm_sched_cfg.data.state. So a new stub function is created and address
2329 // of tm_sched_cfg is passed. This is one-of case where we need to add test specific
2330 // code in production code.
2331 err = bcmolt_cfg_get__tm_sched_stub(dev_id, &tm_sched_cfg);
2332 #else
Jason Huangbf45ffb2019-10-30 17:29:02 +08002333 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002334 #endif
Jason Huangbf45ffb2019-10-30 17:29:02 +08002335 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07002336 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 +08002337 return err;
2338 }
2339 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
2340 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
2341 return BCM_ERR_OK;
2342 }
2343
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002344 // bcmbal_tm_sched_owner
2345 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2346
2347 /**< The output of the tm_sched object instance */
2348 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
2349
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002350 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002351 // In upstream it is NNI scheduler
2352 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 -08002353 } else if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002354 // In downstream it is PON scheduler
2355 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2356 }
2357
2358 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2359
2360 // bcmbal_tm_sched_type
2361 // set the deafult policy to strict priority
2362 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2363
2364 // num_priorities: Max number of strict priority scheduling elements
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002365 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, NUM_OF_PRIORITIES);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002366
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002367 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2368 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002369 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
2370 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002371 return err;
2372 }
2373
2374 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2375 direction.c_str(), tm_sched_key.id, intf_id);
2376 return BCM_ERR_OK;
2377}
2378
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002379bcmos_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 -07002380 uint32_t alloc_id, ::tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
2381 ::tech_profile::SchedulingPolicy sched_policy, ::tech_profile::TrafficShapingInfo tf_sh_info,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002382 uint32_t tech_profile_id) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002383
2384 bcmos_errno err;
2385
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002386 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002387 bcmolt_tm_sched_cfg tm_sched_cfg;
2388 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002389 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 -04002390
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002391 // bcmbal_tm_sched_owner
2392 // In downstream it is sub_term scheduler
2393 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002394
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002395 /**< The output of the tm_sched object instance */
2396 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002397
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002398 // bcmbal_tm_sched_parent
2399 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2400 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 +00002401 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 +00002402 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 +00002403 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002404 be achieved using the' virtual' type of attachment.
2405 tm_sched_owner.u.sub_term.intf_id = intf_id;
2406 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2407 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002408
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002409 // bcmbal_tm_sched_type
2410 // set the deafult policy to strict priority
2411 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002412
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002413 // num_priorities: Max number of strict priority scheduling elements
2414 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002415
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002416 // bcmbal_tm_shaping
2417 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2418 uint32_t cir = tf_sh_info.cir();
2419 uint32_t pir = tf_sh_info.pir();
2420 uint32_t burst = tf_sh_info.pbs();
2421 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2422 cir, pir, burst);
2423 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2424 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2425 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2426 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2427 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2428 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002429 }
2430
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002431 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002432 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002433 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Girish Gowdra72cbee92021-11-05 15:16:18 -07002434intf_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, \
2435port_no, tm_sched_cfg.hdr.hdr.err_text, err);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002436 return err;
2437 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002438 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2439uni_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 -08002440
2441 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002442 bcmolt_itupon_alloc_cfg cfg;
2443 bcmolt_itupon_alloc_key key = { };
2444 key.pon_ni = intf_id;
2445 key.alloc_id = alloc_id;
2446 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
Burak Gurdag623fada2021-04-20 22:02:36 +00002447 /*
2448 PIR: Maximum Bandwidth
2449 CIR: Assured Bandwidth
2450 GIR: Fixed Bandwidth
2451 */
Burak Gurdag03919c72020-02-04 22:46:57 +00002452 int pir_bw = tf_sh_info.pir()*125; // conversion from kbps to bytes/sec
2453 int cir_bw = tf_sh_info.cir()*125; // conversion from kbps to bytes/sec
Burak Gurdag623fada2021-04-20 22:02:36 +00002454 int gir_bw = tf_sh_info.gir()*125; // conversion from kbps to bytes/sec
2455 int guaranteed_bw = cir_bw+gir_bw;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002456 //offset to match bandwidth granularity
2457 int offset_pir_bw = pir_bw%bw_granularity;
Burak Gurdag623fada2021-04-20 22:02:36 +00002458 int offset_gir_bw = gir_bw%bw_granularity;
2459 int offset_guaranteed_bw = guaranteed_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002460
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002461 pir_bw = pir_bw - offset_pir_bw;
Burak Gurdag623fada2021-04-20 22:02:36 +00002462 gir_bw = gir_bw - offset_gir_bw;
2463 guaranteed_bw = guaranteed_bw - offset_guaranteed_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002464
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002465 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002466
Burak Gurdag623fada2021-04-20 22:02:36 +00002467 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);
2468
2469 if (pir_bw == 0) {
2470 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be at least %d bytes/sec\n",
2471 (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2472 return BCM_ERR_PARM;
2473 } else if (pir_bw < guaranteed_bw) {
2474 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed bandwidth (%d)\n",
2475 pir_bw, guaranteed_bw);
2476 return BCM_ERR_PARM;
2477 }
2478
2479 // Setting additional bw eligibility and validating bw provisionings
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002480 switch (additional_bw) {
Burak Gurdag623fada2021-04-20 22:02:36 +00002481
2482 case tech_profile::AdditionalBW::AdditionalBW_BestEffort: //AdditionalBW_BestEffort - For T-Cont types 4 & 5
2483 if (pir_bw == guaranteed_bw) {
2484 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2485bandwidth for additional bandwidth eligibility of type Best Effort\n");
2486 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002487 }
2488 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2489 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002490
2491 case tech_profile::AdditionalBW::AdditionalBW_NA: //AdditionalBW_NA - For T-Cont types 3 & 5
2492 if (guaranteed_bw == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002493 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2494additional bandwidth eligibility of type Non-Assured (NA)\n");
2495 return BCM_ERR_PARM;
Burak Gurdag623fada2021-04-20 22:02:36 +00002496 } else if (pir_bw == guaranteed_bw) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002497 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
Burak Gurdag623fada2021-04-20 22:02:36 +00002498bandwidth for additional bandwidth eligibility of type Non-Assured\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002499 return BCM_ERR_PARM;
2500 }
2501 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2502 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002503
2504 case tech_profile::AdditionalBW::AdditionalBW_None: //AdditionalBW_None - For T-Cont types 1 & 2
2505 if (guaranteed_bw != pir_bw) {
2506 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be equal to maximum bandwidth \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002507for additional bandwidth eligibility of type None\n");
2508 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002509 }
2510 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2511 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002512
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002513 default:
Burak Gurdag623fada2021-04-20 22:02:36 +00002514 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid additional bandwidth eligibility value (%d) supplied.\n", additional_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002515 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002516 }
Burak Gurdag623fada2021-04-20 22:02:36 +00002517
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002518 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2519 in a fine granularity. */
2520 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
Burak Gurdag623fada2021-04-20 22:02:36 +00002521 /* Since we can assign minimum 64000 bytes/sec for cbr_rt_bw, we prefer assigning
2522 gir_bw to cbr_nrt_bw to allow smaller amounts.
2523 TODO: Specify CBR_RT_BW and CBR_NRT_BW separately from VOLTHA */
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002524 /* Fixed Bandwidth with no critical requirement of shaping */
Burak Gurdag623fada2021-04-20 22:02:36 +00002525 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, gir_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002526 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
Burak Gurdag623fada2021-04-20 22:02:36 +00002527 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, guaranteed_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002528 /* Maximum allocated bandwidth allowed for this alloc ID */
2529 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
Burak Gurdag623fada2021-04-20 22:02:36 +00002530
2531 if (pir_bw == gir_bw) { // T-Cont Type 1 --> set alloc type to NONE
2532 // the condition cir_bw == 0 is implicitly satistied
2533 OPENOLT_LOG(INFO, openolt_log_id, "Setting alloc type to NONE since maximum bandwidth is equal to fixed bandwidth\n");
2534 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NONE);
2535 } else { // For other T-Cont types, set alloc type to NSR. TODO: read the default from a config file.
2536 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
2537 }
2538
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002539 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002540 for skipped allocations during quiet window */
2541 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2542 /**< Allocation Profile index for CBR non-RT Bandwidth */
2543 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2544 /**< Allocation Profile index for CBR RT Bandwidth */
2545 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2546 /**< Alloc ID Weight used in case of Extended DBA mode */
2547 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2548 /**< Alloc ID Priority used in case of Extended DBA mode */
2549 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2550 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002551
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302552 bcmolt_onu_state onu_state;
2553 bool wait_for_alloc_cfg_cmplt = false;
2554 err = get_onu_state((bcmolt_interface)intf_id, (bcmolt_onu_id)onu_id, &onu_state);
2555 if (err) {
2556 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch onu status, intf_id = %d, onu_id = %d, err = %s\n",
2557 intf_id, onu_id, bcmos_strerror(err));
2558 return err;
2559 } else if (onu_state == BCMOLT_ONU_STATE_ACTIVE) {
2560 wait_for_alloc_cfg_cmplt = true;
2561 }
2562
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002563 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002564 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002565 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 -07002566port_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 -08002567 return err;
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302568 } else if (wait_for_alloc_cfg_cmplt) {
2569 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
2570 if (err) {
2571 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 +05302572port_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 +05302573 return err;
Girish Gowdra72cbee92021-11-05 15:16:18 -07002574 }
2575 } else {
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302576 OPENOLT_LOG(INFO, openolt_log_id, "onu not active, not waiting for alloc cfg complete, onu_state = %d, intf = %d, onu=%d\n",
2577 onu_state, intf_id, onu_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302578 }
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302579
Girish Gowdra96461052019-11-22 20:13:59 +05302580 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
2581port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
2582
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002583 }
2584
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002585 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002586}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002587
Girish Gowdra252f4972020-09-07 21:24:01 -07002588Status CreateTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002589 uint32_t intf_id = traffic_scheds->intf_id();
2590 uint32_t onu_id = traffic_scheds->onu_id();
2591 uint32_t uni_id = traffic_scheds->uni_id();
2592 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002593 std::string direction;
2594 unsigned int alloc_id;
Girish Gowdra252f4972020-09-07 21:24:01 -07002595 ::tech_profile::SchedulerConfig sched_config;
2596 ::tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002597 uint32_t priority;
2598 uint32_t weight;
Girish Gowdra252f4972020-09-07 21:24:01 -07002599 ::tech_profile::SchedulingPolicy sched_policy;
2600 ::tech_profile::TrafficShapingInfo traffic_shaping_info;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002601 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002602 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002603
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002604 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002605 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002606
2607 direction = GetDirection(traffic_sched.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002608 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002609 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002610 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002611
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002612 alloc_id = traffic_sched.alloc_id();
2613 sched_config = traffic_sched.scheduler();
2614 additional_bw = sched_config.additional_bw();
2615 priority = sched_config.priority();
2616 weight = sched_config.weight();
2617 sched_policy = sched_config.sched_policy();
2618 traffic_shaping_info = traffic_sched.traffic_shaping_info();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002619 tech_profile_id = traffic_sched.tech_profile_id();
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002620 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002621 sched_policy, traffic_shaping_info, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002622 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002623 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002624 return bcm_to_grpc_err(err, "Failed to create scheduler");
2625 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002626 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002627 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002628}
Jonathan Davis70c21812018-07-19 15:32:10 -04002629
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002630bcmos_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 -04002631
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002632 bcmos_errno err;
Girish Gowdra72cbee92021-11-05 15:16:18 -07002633 bcmolt_onu_state onu_state;
Girish Gowdra96461052019-11-22 20:13:59 +05302634 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002635
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002636 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002637 bcmolt_itupon_alloc_cfg cfg;
2638 bcmolt_itupon_alloc_key key = { };
2639 key.pon_ni = intf_id;
2640 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302641 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002642
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302643 bcmolt_onu_state onu_state;
2644 bool wait_for_alloc_cfg_cmplt = false;
2645 err = get_onu_state((bcmolt_interface)intf_id, (bcmolt_onu_id)onu_id, &onu_state);
2646 if (err) {
2647 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch onu status, intf_id = %d, onu_id = %d, err = %s\n",
2648 intf_id, onu_id, bcmos_strerror(err));
2649 return err;
2650 } else if (onu_state == BCMOLT_ONU_STATE_ACTIVE) {
2651 wait_for_alloc_cfg_cmplt = true;
2652 }
2653
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002654 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002655 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2656 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07002657 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s (%d)\n",
2658 direction.c_str(), intf_id, alloc_id, cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002659 return err;
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302660 } else if (wait_for_alloc_cfg_cmplt) {
2661 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2662 if (err) {
2663 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2664pon_intf %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,intf_id,alloc_id, bcmos_strerror(err));
2665 return err;
2666 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302667 } else {
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302668 OPENOLT_LOG(INFO, openolt_log_id, "onu not active, not waiting for alloc cfg complete, onu_state = %d, intf = %d, onu=%d\n",
2669 onu_state, intf_id, onu_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302670 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002671 } else if (direction == downstream) {
2672 bcmolt_tm_sched_cfg cfg;
2673 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002674
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002675 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2676 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302677 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002678 } else {
2679 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2680 return BCM_ERR_OK;
2681 }
Girish Gowdra96461052019-11-22 20:13:59 +05302682
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002683 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2684 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2685 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002686 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
Girish Gowdra72cbee92021-11-05 15:16:18 -07002687intf_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 +00002688 return err;
2689 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002690 }
2691
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002692 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d, tech_profile_id %d\n",
2693 direction.c_str(), sched_id, intf_id, onu_id, tech_profile_id);
2694 free_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002695 return BCM_ERR_OK;
2696}
2697
Girish Gowdra252f4972020-09-07 21:24:01 -07002698Status RemoveTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002699 uint32_t intf_id = traffic_scheds->intf_id();
2700 uint32_t onu_id = traffic_scheds->onu_id();
2701 uint32_t uni_id = traffic_scheds->uni_id();
2702 std::string direction;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002703 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002704 bcmos_errno err;
2705
2706 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002707 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002708
2709 direction = GetDirection(traffic_sched.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002710 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002711 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002712 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002713
2714 int alloc_id = traffic_sched.alloc_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002715 int tech_profile_id = traffic_sched.tech_profile_id();
2716 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002717 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002718 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002719 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2720 }
2721 }
2722 return Status::OK;
2723}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002724
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002725bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2726 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002727 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002728 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2729 bcmolt_tm_qmp_key tm_qmp_key;
2730 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002731
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002732 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2733 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002734 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed tm queue mapping profile count is 16.\n");
2735 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002736 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002737
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002738 tm_qmp_key.id = tm_qmp_id;
2739 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2740 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2741 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002742
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002743 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2744 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2745 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002746 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2747 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002748
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002749 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002750 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002751 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2752 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002753 return err;
2754 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002755
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002756 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2757 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002758 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002759}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002760
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002761bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2762 bcmos_errno err;
2763 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2764 bcmolt_tm_qmp_key tm_qmp_key;
2765 tm_qmp_key.id = tm_qmp_id;
2766
2767 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2768 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2769 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002770 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2771 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002772 return err;
2773 }
2774
2775 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2776 tm_qmp_key.id);
2777 return BCM_ERR_OK;
2778}
2779
2780bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2781 bcmos_errno err;
2782
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002783 /* Create default queues on the given PON/NNI scheduler */
2784 for (int queue_id = 0; queue_id < NUMBER_OF_DEFAULT_INTERFACE_QUEUES; queue_id++) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002785 bcmolt_tm_queue_cfg tm_queue_cfg;
2786 bcmolt_tm_queue_key tm_queue_key = {};
2787 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2788 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002789 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2790 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2791 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002792
2793 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2794 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2795 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2796
2797 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2798 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002799 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", \
2800 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 +00002801 return err;
2802 }
2803
2804 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2805 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2806 }
2807 return BCM_ERR_OK;
2808}
2809
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002810bcmos_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 +00002811 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 +00002812 bcmos_errno err;
2813 bcmolt_tm_queue_cfg cfg;
2814 bcmolt_tm_queue_key key = { };
2815 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 +00002816gemport_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 +00002817
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002818 key.sched_id = (direction == upstream) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002819 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002820
2821 if (priority > 7) {
2822 return BCM_ERR_RANGE;
2823 }
2824
2825 /* FIXME: The upstream queues have to be created once only.
2826 The upstream queues on the NNI scheduler are shared by all subscribers.
2827 When the first scheduler comes in, the queues get created, and are re-used by all others.
2828 Also, these queues should be present until the last subscriber exits the system.
2829 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2830
2831 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2832 for each GEM in TECH PROFILE */
2833 key.id = queue_id_list[priority];
2834
2835 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2836 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2837 key.id = 0;
2838 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2839 }
2840 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2841 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2842 }
2843 else {
2844 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2845 }
2846
2847 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2848
2849 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2850 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
Girish Gowdra5287fde2021-07-31 00:41:45 +00002851 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002852
2853 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2854 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002855 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
Girish Gowdra72cbee92021-11-05 15:16:18 -07002856sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, tech_profile_id %d, err = %s (%d)\n", \
2857 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 +00002858 return err;
2859 }
2860
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302861 if (direction == upstream || direction == downstream) {
Thiyagarajan Subramani19168f52021-05-25 23:26:41 +05302862 Status st = install_gem_port(access_intf_id, onu_id, uni_id, gemport_id, board_technology);
Girish Gowdra252f4972020-09-07 21:24:01 -07002863 if (st.error_code() != grpc::StatusCode::ALREADY_EXISTS && st.error_code() != grpc::StatusCode::OK) {
2864 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);
2865 return BCM_ERR_INTERNAL;
2866 }
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002867 if (direction == upstream) {
2868 // Create the pon-gem to onu-uni mapping
2869 pon_gem pg(access_intf_id, gemport_id);
2870 onu_uni ou(onu_id, uni_id);
2871 bcmos_fastlock_lock(&pon_gem_to_onu_uni_map_lock);
2872 pon_gem_to_onu_uni_map[pg] = ou;
2873 bcmos_fastlock_unlock(&pon_gem_to_onu_uni_map_lock, 0);
2874 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002875 }
2876
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002877 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 +00002878intf_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 +00002879 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002880}
2881
Girish Gowdra252f4972020-09-07 21:24:01 -07002882Status CreateTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002883 uint32_t intf_id = traffic_queues->intf_id();
2884 uint32_t onu_id = traffic_queues->onu_id();
2885 uint32_t uni_id = traffic_queues->uni_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002886 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002887 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002888 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002889 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002890 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 +00002891
2892 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2893 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2894 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2895 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002896 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002897
2898 direction = GetDirection(traffic_queue.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002899 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002900 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002901 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002902
2903 queues_priority_q[i] = traffic_queue.priority();
2904 queues_pbit_map[i] = traffic_queue.pbit_map();
2905 }
2906
2907 std::vector<uint32_t> tmq_map_profile(8, 0);
2908 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2909 queues_priority_q, COUNT_OF(queues_priority_q));
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002910 sched_id = (direction == upstream) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002911 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002912
2913 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2914 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002915 err = CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2916 if (err != BCM_ERR_OK) {
2917 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2918 return bcm_to_grpc_err(err, "Failed to create tm queue mapping profile");
2919 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002920 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2921 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2922 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2923 }
2924 }
2925
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002926 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002927 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002928
2929 direction = GetDirection(traffic_queue.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002930 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002931 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002932 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002933
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002934 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 +00002935
Girish Gowdruf26cf882019-05-01 23:47:58 -07002936 // If the queue exists already, lets not return failure and break the loop.
2937 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002938 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002939 return bcm_to_grpc_err(err, "Failed to create queue");
2940 }
2941 }
2942 return Status::OK;
2943}
2944
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002945bcmos_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 +00002946 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 +00002947 bcmolt_tm_queue_cfg cfg;
2948 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002949 bcmos_errno err;
2950
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302951 // Gemports are bi-directional (except in multicast case). We create the gem port when we create the
2952 // upstream/downstream queue (see CreateQueue function) and it makes sense to delete them when remove the queues.
2953 // For multicast case we do not manage the install/remove of gem port in agent application. It is managed by BAL.
2954 if (direction == upstream || direction == downstream) {
Thiyagarajan Subramani19168f52021-05-25 23:26:41 +05302955 Status st = remove_gem_port(access_intf_id, onu_id, uni_id, gemport_id, board_technology);
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302956 if (st.error_code() != grpc::StatusCode::OK) {
2957 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 -07002958 // We should further cleanup proceed, do not return error yet..
2959 // return BCM_ERR_INTERNAL;
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302960 }
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002961 if (direction == upstream) {
2962 // Remove the pon-gem to onu-uni mapping
2963 pon_gem pg(access_intf_id, gemport_id);
2964 bcmos_fastlock_lock(&pon_gem_to_onu_uni_map_lock);
2965 pon_gem_to_onu_uni_map.erase(pg);
2966 bcmos_fastlock_unlock(&pon_gem_to_onu_uni_map_lock, 0);
2967 }
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302968 }
2969
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002970 if (direction == downstream) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002971 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2972 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 +00002973 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002974 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002975 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 -08002976 return BCM_ERR_OK;
2977 }
2978 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002979 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2980 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002981 return BCM_ERR_OK;
2982 }
2983
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002984 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2985 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2986 // Reset the queue id to 0 when using fixed queue.
2987 key.id = 0;
2988 }
2989 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2990 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2991 }
2992 else {
2993 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2994 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002995
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002996 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2997 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002998 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002999 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 -07003000tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s (%d)\n",
3001 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 -08003002 return err;
3003 }
3004
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003005 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
3006intf_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 -08003007
3008 return BCM_ERR_OK;
3009}
3010
Girish Gowdra252f4972020-09-07 21:24:01 -07003011Status RemoveTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003012 uint32_t intf_id = traffic_queues->intf_id();
3013 uint32_t onu_id = traffic_queues->onu_id();
3014 uint32_t uni_id = traffic_queues->uni_id();
3015 uint32_t port_no = traffic_queues->port_no();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00003016 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003017 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003018 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003019 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003020 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 -07003021 Status ret_code = Status::OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003022
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003023 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07003024 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003025
3026 direction = GetDirection(traffic_queue.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08003027 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003028 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08003029 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003030
Burak Gurdag2f2618c2020-04-23 13:20:30 +00003031 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 -08003032 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003033 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdra72cbee92021-11-05 15:16:18 -07003034 ret_code = bcm_to_grpc_err(err, "Failed to remove one or more queues");
3035 // Do not return here. We should continue to remove the remaining queues and its associated gem ports
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003036 }
Jonathan Davis70c21812018-07-19 15:32:10 -04003037 }
3038
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08003039 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE && (direction == upstream || \
3040 direction == downstream && is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id))) {
3041 sched_id = (direction == upstream) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00003042 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003043
3044 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
3045 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05003046 err = RemoveTrafficQueueMappingProfile(tm_qmp_id);
3047 if (err != BCM_ERR_OK) {
3048 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, err = %s\n", bcmos_strerror(err));
3049 return bcm_to_grpc_err(err, "Failed to remove tm queue mapping profile");
3050 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003051 }
3052 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003053 clear_qos_type(intf_id, onu_id, uni_id);
Girish Gowdra72cbee92021-11-05 15:16:18 -07003054 return ret_code;
Jonathan Davis70c21812018-07-19 15:32:10 -04003055}
Jason Huangbf45ffb2019-10-30 17:29:02 +08003056
Girish Gowdra252f4972020-09-07 21:24:01 -07003057Status PerformGroupOperation_(const ::openolt::Group *group_cfg) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003058
3059 bcmos_errno err;
3060 bcmolt_group_key key = {};
3061 bcmolt_group_cfg grp_cfg_obj;
3062 bcmolt_group_members_update grp_mem_upd;
3063 bcmolt_members_update_command grp_mem_upd_cmd;
3064 bcmolt_group_member_info member_info = {};
3065 bcmolt_group_member_info_list_u8 members = {};
3066 bcmolt_intf_ref interface_ref = {};
3067 bcmolt_egress_qos egress_qos = {};
3068 bcmolt_tm_sched_ref tm_sched_ref = {};
3069 bcmolt_action a_val = {};
3070
3071 uint32_t group_id = group_cfg->group_id();
3072
3073 OPENOLT_LOG(INFO, openolt_log_id, "PerformGroupOperation request received for Group %d\n", group_id);
3074
3075 if (group_id >= 0) {
3076 key.id = group_id;
3077 }
3078 else {
3079 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
3080 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
3081 }
3082
3083 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3084 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
3085
3086 OPENOLT_LOG(INFO, openolt_log_id, "Checking if Group %d exists...\n",group_id);
3087
3088 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
3089 if (err != BCM_ERR_OK) {
3090 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
3091 return bcm_to_grpc_err(err, "Error in querying group");
3092 }
3093
3094 members.len = group_cfg->members_size();
3095
3096 // IMPORTANT: A member cannot be added to a group if the group type is not determined.
3097 // Group type is determined after a flow is assigned to it.
3098 // Therefore, a group must be created first, then a flow (with multicast type) must be assigned to it.
3099 // Only then we can add members to the group.
3100
3101 // if group does not exist, create it and return.
3102 if (grp_cfg_obj.data.state == BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
3103
3104 if (members.len != 0) {
3105 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);
3106 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Non-empty member list given for non-existent group");
3107 } else {
3108
3109 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3110 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, cookie, key.id);
3111
3112 /* Setting group actions and action parameters, if any.
3113 Only remove_outer_tag and translate_inner_tag actions and i_vid action parameter
3114 are supported for multicast groups in BAL 3.1.
3115 */
3116 const ::openolt::Action& action = group_cfg->action();
3117 const ::openolt::ActionCmd &cmd = action.cmd();
3118
3119 bcmolt_action_cmd_id cmd_bmask = BCMOLT_ACTION_CMD_ID_NONE;
3120 if (cmd.remove_outer_tag()) {
3121 OPENOLT_LOG(INFO, openolt_log_id, "Action remove_outer_tag applied to Group %d.\n", group_id);
3122 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
3123 }
3124
3125 if (cmd.translate_inner_tag()) {
3126 OPENOLT_LOG(INFO, openolt_log_id, "Action translate_inner_tag applied to Group %d.\n", group_id);
3127 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG);
3128 }
3129
3130 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, cmd_bmask);
3131
3132 if (action.i_vid()) {
3133 OPENOLT_LOG(INFO, openolt_log_id, "Setting action parameter i_vid=%d for Group %d.\n", action.i_vid(), group_id);
3134 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
3135 }
3136
3137 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, action, a_val);
3138
3139 // Create group
3140 err = bcmolt_cfg_set(dev_id, &(grp_cfg_obj.hdr));
3141
3142 if (BCM_ERR_OK != err) {
3143 BCM_LOG(ERROR, openolt_log_id, "Failed to create Group %d, err = %s (%d)\n", key.id, bcmos_strerror(err), err);
3144 return bcm_to_grpc_err(err, "Error in creating group");
3145 }
3146
3147 BCM_LOG(INFO, openolt_log_id, "Group %d has been created and configured with empty member list.\n", key.id);
3148 return Status::OK;
3149 }
3150 }
3151
3152 // The group already exists. Continue configuring it according to the update member command.
3153
3154 OPENOLT_LOG(INFO, openolt_log_id, "Configuring existing Group %d.\n",group_id);
3155
3156 // MEMBER LIST CONSTRUCTION
3157 // Note that members.len can be 0 here. if the group already exists and the command is SET then sending
3158 // empty list to the group is a legit operation and this actually empties the member list.
3159 members.arr = (bcmolt_group_member_info*)bcmos_calloc((members.len)*sizeof(bcmolt_group_member_info));
3160
3161 if (!members.arr) {
3162 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to allocate memory for group member list.\n");
3163 return grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "Memory exhausted during member list creation");
3164 }
3165
3166 /* SET GROUP MEMBERS UPDATE COMMAND */
Girish Gowdra252f4972020-09-07 21:24:01 -07003167 ::openolt::Group::GroupMembersCommand command = group_cfg->command();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003168 switch(command) {
Girish Gowdra252f4972020-09-07 21:24:01 -07003169 case ::openolt::Group::SET_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003170 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_SET;
3171 OPENOLT_LOG(INFO, openolt_log_id, "Setting %d members for Group %d.\n", members.len, group_id);
3172 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003173 case ::openolt::Group::ADD_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003174 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_ADD;
3175 OPENOLT_LOG(INFO, openolt_log_id, "Adding %d members to Group %d.\n", members.len, group_id);
3176 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003177 case ::openolt::Group::REMOVE_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003178 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_REMOVE;
3179 OPENOLT_LOG(INFO, openolt_log_id, "Removing %d members from Group %d.\n", members.len, group_id);
3180 break;
3181 default :
3182 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid value %d for group member command.\n", command);
3183 bcmos_free(members.arr);
3184 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group member command");
3185 }
3186
3187 // SET MEMBERS LIST
3188 for (int i = 0; i < members.len; i++) {
3189
Girish Gowdra252f4972020-09-07 21:24:01 -07003190 if (command == ::openolt::Group::REMOVE_MEMBERS) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003191 OPENOLT_LOG(INFO, openolt_log_id, "Removing group member %d from group %d\n",i,key.id);
3192 } else {
3193 OPENOLT_LOG(INFO, openolt_log_id, "Adding group member %d to group %d\n",i,key.id);
3194 }
3195
Girish Gowdra252f4972020-09-07 21:24:01 -07003196 ::openolt::GroupMember *member = (::openolt::GroupMember *) &group_cfg->members()[i];
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003197
3198 // Set member interface type
Girish Gowdra252f4972020-09-07 21:24:01 -07003199 ::openolt::GroupMember::InterfaceType if_type = member->interface_type();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003200 switch(if_type){
Girish Gowdra252f4972020-09-07 21:24:01 -07003201 case ::openolt::GroupMember::PON :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003202 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_PON);
3203 OPENOLT_LOG(INFO, openolt_log_id, "Interface type PON is assigned to GroupMember %d\n",i);
3204 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003205 case ::openolt::GroupMember::EPON_1G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003206 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_1_G);
3207 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_1G is assigned to GroupMember %d\n",i);
3208 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003209 case ::openolt::GroupMember::EPON_10G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003210 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_10_G);
3211 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_10G is assigned to GroupMember %d\n",i);
3212 break;
3213 default :
3214 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid interface type value %d for GroupMember %d.\n",if_type,i);
3215 bcmos_free(members.arr);
3216 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface type for a group member");
3217 }
3218
3219 // Set member interface id
3220 if (member->interface_id() >= 0) {
3221 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_id, member->interface_id());
3222 OPENOLT_LOG(INFO, openolt_log_id, "Interface %d is assigned to GroupMember %d\n", member->interface_id(), i);
3223 } else {
3224 bcmos_free(members.arr);
3225 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface id for a group member");
3226 }
3227
3228 // Set member interface_ref
3229 BCMOLT_FIELD_SET(&member_info, group_member_info, intf, interface_ref);
3230
3231 // Set member gem_port_id. This must be a multicast gemport.
3232 if (member->gem_port_id() >= 0) {
3233 BCMOLT_FIELD_SET(&member_info, group_member_info, svc_port_id, member->gem_port_id());
3234 OPENOLT_LOG(INFO, openolt_log_id, "GEM Port %d is assigned to GroupMember %d\n", member->gem_port_id(), i);
3235 } else {
3236 bcmos_free(members.arr);
3237 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid gem port id for a group member");
3238 }
3239
3240 // Set member scheduler id and queue_id
3241 uint32_t tm_sched_id = get_default_tm_sched_id(member->interface_id(), downstream);
3242 OPENOLT_LOG(INFO, openolt_log_id, "Scheduler %d is assigned to GroupMember %d\n", tm_sched_id, i);
3243 BCMOLT_FIELD_SET(&tm_sched_ref, tm_sched_ref, id, tm_sched_id);
3244 BCMOLT_FIELD_SET(&egress_qos, egress_qos, tm_sched, tm_sched_ref);
3245
3246 // We assume that all multicast traffic destined to a PON port is using the same fixed queue.
3247 uint32_t tm_queue_id;
3248 if (member->priority() >= 0 && member->priority() < NUMBER_OF_DEFAULT_INTERFACE_QUEUES) {
3249 tm_queue_id = queue_id_list[member->priority()];
3250 OPENOLT_LOG(INFO, openolt_log_id, "Queue %d is assigned to GroupMember %d\n", tm_queue_id, i);
3251 BCMOLT_FIELD_SET(&egress_qos, egress_qos, type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
3252 BCMOLT_FIELD_SET(&egress_qos.u.fixed_queue, egress_qos_fixed_queue, queue_id, tm_queue_id);
3253 } else {
3254 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid fixed queue priority/ID %d for GroupMember %d\n", member->priority(), i);
3255 bcmos_free(members.arr);
3256 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid queue priority for a group member");
3257 }
3258
3259 BCMOLT_FIELD_SET(&member_info, group_member_info, egress_qos, egress_qos);
3260 BCMOLT_ARRAY_ELEM_SET(&(members), i, member_info);
3261 }
3262
3263 BCMOLT_OPER_INIT(&grp_mem_upd, group, members_update, key);
3264 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.members, members);
3265 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.command, grp_mem_upd_cmd);
3266
3267 err = bcmolt_oper_submit(dev_id, &(grp_mem_upd.hdr));
3268 bcmos_free(members.arr);
3269
3270 if (BCM_ERR_OK != err) {
3271 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);
3272 return bcm_to_grpc_err(err, "Failed to submit members update operation for the group");
3273 }
3274
3275 OPENOLT_LOG(INFO, openolt_log_id, "Successfully submitted members update operation for Group %d\n", key.id);
3276
3277 return Status::OK;
3278}
Burak Gurdageb4ca2e2020-06-15 07:48:26 +00003279
3280Status DeleteGroup_(uint32_t group_id) {
3281
3282 bcmos_errno err = BCM_ERR_OK;
3283 bcmolt_group_cfg grp_cfg_obj;
3284 bcmolt_group_key key = {};
3285
3286
3287 OPENOLT_LOG(INFO, openolt_log_id, "Delete request received for group %d\n", group_id);
3288
3289 if (group_id >= 0) {
3290 key.id = group_id;
3291 } else {
3292 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
3293 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
3294 }
3295
3296 /* init the BAL INIT API */
3297 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3298
3299 OPENOLT_LOG(DEBUG, openolt_log_id, "Checking if group %d exists...\n",group_id);
3300
3301 // CONFIGURE GROUP MEMBERS
3302 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
3303 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
3304
3305 if (err != BCM_ERR_OK) {
3306 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
3307 return bcm_to_grpc_err(err, "Error in querying group");
3308 }
3309
3310 if (grp_cfg_obj.data.state != BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
3311 OPENOLT_LOG(DEBUG, openolt_log_id, "Group %d exists. Will be deleted.\n",group_id);
3312 err = bcmolt_cfg_clear(dev_id, &(grp_cfg_obj.hdr));
3313 if (err != BCM_ERR_OK) {
3314 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d cannot be deleted err = %s (%d).\n", group_id, bcmos_strerror(err), err);
3315 return bcm_to_grpc_err(err, "Failed to delete group");;
3316 }
3317 } else {
3318 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d does not exist.\n", group_id);
3319 return Status(grpc::StatusCode::NOT_FOUND, "Group not found");
3320 }
3321
3322 OPENOLT_LOG(INFO, openolt_log_id, "Group %d has been deleted successfully.\n", group_id);
3323 return Status::OK;
Jason Huang1d9cfce2020-05-20 22:58:47 +08003324}
3325
Girish Gowdra252f4972020-09-07 21:24:01 -07003326Status GetLogicalOnuDistanceZero_(uint32_t intf_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003327 bcmos_errno err = BCM_ERR_OK;
3328 uint32_t mld = 0;
3329 double LD0;
3330
3331 err = getOnuMaxLogicalDistance(intf_id, &mld);
3332 if (err != BCM_ERR_OK) {
3333 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3334 }
3335
3336 LD0 = LOGICAL_DISTANCE(mld*1000, MINIMUM_ONU_RESPONSE_RANGING_TIME, ONU_BIT_TRANSMISSION_DELAY);
3337 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance zero is %f, (PON %d)\n", LD0, intf_id);
3338 response->set_intf_id(intf_id);
3339 response->set_logical_onu_distance_zero(LD0);
3340
3341 return Status::OK;
3342}
3343
Girish Gowdra252f4972020-09-07 21:24:01 -07003344Status GetLogicalOnuDistance_(uint32_t intf_id, uint32_t onu_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003345 bcmos_errno err = BCM_ERR_OK;
3346 bcmolt_itu_onu_params itu = {};
3347 bcmolt_onu_cfg onu_cfg;
3348 bcmolt_onu_key onu_key = {};
3349 uint32_t mld = 0;
3350 double LDi;
3351
3352 onu_key.pon_ni = intf_id;
3353 onu_key.onu_id = onu_id;
3354
3355 err = getOnuMaxLogicalDistance(intf_id, &mld);
3356 if (err != BCM_ERR_OK) {
3357 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3358 }
3359
3360 /* Initialize the API struct. */
3361 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
3362 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
3363 BCMOLT_FIELD_SET_PRESENT(&itu, itu_onu_params, ranging_time);
3364 BCMOLT_FIELD_SET(&onu_cfg.data, onu_cfg_data, itu, itu);
3365 #ifdef TEST_MODE
3366 // It is impossible to mock the setting of onu_cfg.data.onu_state because
3367 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
3368 // set the onu_cfg.data.onu_state. So a new stub function is created and address
3369 // of onu_cfg is passed. This is one-of case where we need to add test specific
3370 // code in production code.
3371 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
3372 #else
3373 /* Call API function. */
3374 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
3375 #endif
3376 if (err != BCM_ERR_OK) {
3377 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);
3378 return bcm_to_grpc_err(err, "Failed to retrieve ONU ranging time");
3379 }
3380
3381 if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_ACTIVE) {
3382 OPENOLT_LOG(ERROR, openolt_log_id, "ONU is not yet activated (PON %d, ONU id %d)\n", intf_id, onu_id);
3383 return bcm_to_grpc_err(BCM_ERR_PARM, "ONU is not yet activated\n");
3384 }
3385
3386 LDi = LOGICAL_DISTANCE(mld*1000, onu_cfg.data.itu.ranging_time, ONU_BIT_TRANSMISSION_DELAY);
3387 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance is %f, (PON %d, ONU id %d)\n", LDi, intf_id, onu_id);
3388 response->set_intf_id(intf_id);
3389 response->set_onu_id(onu_id);
3390 response->set_logical_onu_distance(LDi);
3391
3392 return Status::OK;
3393}
Burak Gurdag74e3ab82020-12-17 13:35:06 +00003394
3395Status GetOnuStatistics_(uint32_t intf_id, uint32_t onu_id, openolt::OnuStatistics* onu_stats) {
3396 bcmos_errno err;
3397
3398 err = get_onu_statistics((bcmolt_interface_id)intf_id, (bcmolt_onu_id)onu_id, onu_stats);
3399
3400 if (err != BCM_ERR_OK) {
3401 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));
3402 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of ONU statistics failed");
3403 }
3404
3405 OPENOLT_LOG(INFO, openolt_log_id, "retrieved ONU statistics for PON ID = %d, ONU ID = %d\n", (int)intf_id, (int)onu_id);
3406 return Status::OK;
3407}
3408
3409Status GetGemPortStatistics_(uint32_t intf_id, uint32_t gemport_id, openolt::GemPortStatistics* gemport_stats) {
3410 bcmos_errno err;
3411
3412 err = get_gemport_statistics((bcmolt_interface_id)intf_id, (bcmolt_gem_port_id)gemport_id, gemport_stats);
3413
3414 if (err != BCM_ERR_OK) {
3415 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));
3416 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of GEMPORT statistics failed");
3417 }
3418
3419 OPENOLT_LOG(INFO, openolt_log_id, "retrieved GEMPORT statistics for PON ID = %d, GEMPORT ID = %d\n", (int)intf_id, (int)gemport_id);
3420 return Status::OK;
3421}
Orhan Kupusogluec57af02021-05-12 12:38:17 +00003422
3423Status GetPonRxPower_(uint32_t intf_id, uint32_t onu_id, openolt::PonRxPowerData* response) {
3424 bcmos_errno err = BCM_ERR_OK;
3425
3426 // check the PON intf id
3427 if (intf_id >= MAX_SUPPORTED_PON) {
3428 err = BCM_ERR_PARM;
3429 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pon intf_id - intf_id: %d, onu_id: %d\n",
3430 intf_id, onu_id);
3431 return bcm_to_grpc_err(err, "invalid pon intf_id");
3432 }
3433
3434 bcmolt_onu_rssi_measurement onu_oper; /* declare main API struct */
3435 bcmolt_onu_key onu_key; /**< Object key. */
3436 onu_rssi_compltd_key key(intf_id, onu_id);
3437 Queue<onu_rssi_complete_result> queue;
3438
3439 OPENOLT_LOG(INFO, openolt_log_id, "GetPonRxPower - intf_id %d, onu_id %d\n", intf_id, onu_id);
3440
3441 onu_key.onu_id = onu_id;
3442 onu_key.pon_ni = intf_id;
3443 /* Initialize the API struct. */
3444 BCMOLT_OPER_INIT(&onu_oper, onu, rssi_measurement, onu_key);
3445 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
3446 if (err == BCM_ERR_OK) {
3447 // initialize map
3448 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3449 onu_rssi_compltd_map.insert({key, &queue});
3450 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3451 } else {
3452 OPENOLT_LOG(ERROR, openolt_log_id, "failed to measure rssi rx power - intf_id: %d, onu_id: %d, err = %s (%d): %s\n",
3453 intf_id, onu_id, bcmos_strerror(err), err, onu_oper.hdr.hdr.err_text);
3454 return bcm_to_grpc_err(err, "failed to measure rssi rx power");
3455 }
3456
3457 onu_rssi_complete_result completed{};
3458 if (!queue.pop(completed, ONU_RSSI_COMPLETE_WAIT_TIMEOUT)) {
3459 // invalidate the queue pointer
3460 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3461 onu_rssi_compltd_map[key] = NULL;
3462 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3463 err = BCM_ERR_TIMEOUT;
3464 OPENOLT_LOG(ERROR, openolt_log_id, "timeout waiting for RSSI Measurement Completed indication intf_id %d, onu_id %d\n",
3465 intf_id, onu_id);
3466 } else {
3467 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",
3468 completed.pon_intf_id, completed.onu_id, completed.status.c_str(), completed.reason, completed.rx_power_mean_dbm);
3469
3470 response->set_intf_id(completed.pon_intf_id);
3471 response->set_onu_id(completed.onu_id);
3472 response->set_status(completed.status);
3473 response->set_fail_reason(static_cast<::openolt::PonRxPowerData_RssiMeasurementFailReason>(completed.reason));
3474 response->set_rx_power_mean_dbm(completed.rx_power_mean_dbm);
3475 }
3476
3477 // Remove entry from map
3478 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3479 onu_rssi_compltd_map.erase(key);
3480 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3481
3482 if (err == BCM_ERR_OK) {
3483 return Status::OK;
3484 } else {
3485 return bcm_to_grpc_err(err, "timeout waiting for pon rssi measurement complete indication");
3486 }
3487}