blob: a833077911d753d7befeab9471ed54ec1cf03411 [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);
Arthur Syu094df162022-04-21 17:50:06 +0800447 } else if (MODEL_ID == "sda3016ss") {
448 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_12_P_5_G);
449 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_TWO_TO_ONE);
450 BCMOLT_MSG_FIELD_SET (&oper, ras_ddr_mode, BCMOLT_RAS_DDR_USAGE_MODE_TWO_DDRS);
451 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_XGS__8_X_GPON__8_X_WDMA);
452 /* By default setting device mode to XGSPON/GPON combo for sda3016ss.
453 And it can also be configured to Any-PON (XGSPON || GPON) */
454
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000455 }
456 err = bcmolt_oper_submit(dev_id, &oper.hdr);
457 if (err) {
458 failed_enable_device_cnt ++;
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500459 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 +0000460 if (failed_enable_device_cnt == BCM_MAX_DEVS_PER_LINE_CARD) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500461 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 +0000462 return Status(grpc::StatusCode::INTERNAL, "Failed to activate all PON ports");
463 }
464 }
Girish Gowdra72bb4652022-01-18 17:04:30 -0800465 bcmos_usleep(MAC_DEVICE_ACTIVATION_DELAY);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000466 }
467 else {
Thiyagarajan Subramani4e62e172021-06-25 17:31:30 +0530468 OPENOLT_LOG(WARNING, openolt_log_id, "PON device %d already connected\n", dev);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000469 state.activate();
470 }
471 }
472 init_stats();
Shad Ansari627b5782018-08-13 22:49:32 +0000473 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000474 }
Shad Ansariedef2132018-08-10 22:14:50 +0000475
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000476 /* Start CLI */
477 OPENOLT_LOG(INFO, def_log_id, "Starting CLI\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400478 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000479 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400480}
481
482Status Disable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400483 //In the earlier implementation Disabling olt is done by disabling the NNI port associated with that.
484 //In inband scenario instead of using management interface to establish connection with adapter ,NNI interface will be used.
485 //Disabling NNI port on olt disable causes connection loss between adapter and agent.
486 //To overcome this disable is implemented by disabling all the PON ports
487 //associated with the device so as to support both in-band
488 //and out of band scenarios.
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400489
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400490 Status status;
491 int failedCount = 0;
Girish Gowdrae1db2952021-05-04 00:16:54 -0700492 OPENOLT_LOG(INFO, openolt_log_id, "Received disable OLT\n");
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400493 for (int i = 0; i < NumPonIf_(); i++) {
494 status = DisablePonIf_(i);
495 if (!status.ok()) {
496 failedCount+=1;
497 BCM_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", i);
498 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400499 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400500 if (failedCount == 0) {
501 state.deactivate();
Girish Gowdra252f4972020-09-07 21:24:01 -0700502 ::openolt::Indication ind;
503 ::openolt::OltIndication* olt_ind = new ::openolt::OltIndication;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400504 olt_ind->set_oper_state("down");
505 ind.set_allocated_olt_ind(olt_ind);
506 BCM_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
507 oltIndQ.push(ind);
508 return Status::OK;
509 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000510 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400511 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to disable olt ,all the PON ports are still in enabled state");
512 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400513
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400514 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 -0400515}
516
517Status Reenable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400518 Status status;
519 int failedCount = 0;
520 for (int i = 0; i < NumPonIf_(); i++) {
521 status = EnablePonIf_(i);
522 if (!status.ok()) {
523 failedCount+=1;
524 BCM_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", i);
525 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400526 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000527 if (failedCount == 0) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400528 state.activate();
Girish Gowdra252f4972020-09-07 21:24:01 -0700529 ::openolt::Indication ind;
530 ::openolt::OltIndication* olt_ind = new ::openolt::OltIndication;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400531 olt_ind->set_oper_state("up");
532 ind.set_allocated_olt_ind(olt_ind);
533 BCM_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
534 oltIndQ.push(ind);
535 return Status::OK;
536 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000537 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400538 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to re-enable olt ,all the PON ports are still in disabled state");
539 }
540 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 +0000541}
542
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000543inline uint64_t get_flow_status(uint16_t flow_id, uint16_t flow_type, uint16_t data_id) {
544 bcmos_errno err;
545 bcmolt_flow_key flow_key;
546 bcmolt_flow_cfg flow_cfg;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400547
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000548 flow_key.flow_id = flow_id;
549 flow_key.flow_type = (bcmolt_flow_type)flow_type;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400550
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000551 BCMOLT_CFG_INIT(&flow_cfg, flow, flow_key);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400552
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000553 switch (data_id) {
554 case ONU_ID: //onu_id
555 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, onu_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500556 #ifdef TEST_MODE
557 // It is impossible to mock the setting of flow_cfg.data.state because
558 // the actual bcmolt_cfg_get passes the address of flow_cfg.hdr and we cannot
559 // set the flow_cfg.data. So a new stub function is created and address
560 // of flow_cfg is passed. This is one-of case where we need to add test specific
561 // code in production code.
562 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
563 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000564 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500565 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000566 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700567 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get onu_id, err = %s (%d)\n", flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000568 return err;
569 }
570 return flow_cfg.data.onu_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400571 case FLOW_TYPE:
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500572 #ifdef TEST_MODE
573 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
574 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000575 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500576 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000577 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700578 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get flow_type, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000579 return err;
580 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400581 return flow_cfg.key.flow_type;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000582 case SVC_PORT_ID: //svc_port_id
583 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, svc_port_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500584 #ifdef TEST_MODE
585 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
586 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000587 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500588 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000589 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700590 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get svc_port_id, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000591 return err;
592 }
593 return flow_cfg.data.svc_port_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400594 case PRIORITY:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000595 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, priority);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500596 #ifdef TEST_MODE
597 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
598 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000599 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500600 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000601 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700602 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get priority, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000603 return err;
604 }
605 return flow_cfg.data.priority;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400606 case COOKIE: //cookie
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000607 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, cookie);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500608 #ifdef TEST_MODE
609 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
610 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000611 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500612 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000613 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700614 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get cookie, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000615 return err;
616 }
617 return flow_cfg.data.cookie;
618 case INGRESS_INTF_TYPE: //ingress intf_type
619 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500620 #ifdef TEST_MODE
621 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
622 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000623 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500624 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000625 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700626 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get ingress intf_type, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000627 return err;
628 }
629 return flow_cfg.data.ingress_intf.intf_type;
630 case EGRESS_INTF_TYPE: //egress intf_type
631 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500632 #ifdef TEST_MODE
633 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
634 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000635 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500636 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000637 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700638 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress intf_type, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000639 return err;
640 }
641 return flow_cfg.data.egress_intf.intf_type;
642 case INGRESS_INTF_ID: //ingress intf_id
643 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500644 #ifdef TEST_MODE
645 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
646 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000647 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500648 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000649 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700650 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get ingress intf_id, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000651 return err;
652 }
653 return flow_cfg.data.ingress_intf.intf_id;
654 case EGRESS_INTF_ID: //egress intf_id
655 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500656 #ifdef TEST_MODE
657 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
658 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000659 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500660 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000661 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700662 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress intf_id, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000663 return err;
664 }
665 return flow_cfg.data.egress_intf.intf_id;
666 case CLASSIFIER_O_VID:
667 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500668 #ifdef TEST_MODE
669 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
670 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000671 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500672 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000673 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700674 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier o_vid, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000675 return err;
676 }
677 return flow_cfg.data.classifier.o_vid;
678 case CLASSIFIER_O_PBITS:
679 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500680 #ifdef TEST_MODE
681 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
682 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000683 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500684 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000685 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700686 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier o_pbits, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000687 return err;
688 }
689 return flow_cfg.data.classifier.o_pbits;
690 case CLASSIFIER_I_VID:
691 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500692 #ifdef TEST_MODE
693 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
694 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000695 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500696 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000697 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700698 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier i_vid, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000699 return err;
700 }
701 return flow_cfg.data.classifier.i_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400702 case CLASSIFIER_I_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000703 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500704 #ifdef TEST_MODE
705 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
706 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000707 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500708 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000709 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700710 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier i_pbits, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000711 return err;
712 }
713 return flow_cfg.data.classifier.i_pbits;
714 case CLASSIFIER_ETHER_TYPE:
715 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500716 #ifdef TEST_MODE
717 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
718 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000719 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500720 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000721 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700722 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier ether_type, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000723 return err;
724 }
725 return flow_cfg.data.classifier.ether_type;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400726 case CLASSIFIER_IP_PROTO:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000727 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500728 #ifdef TEST_MODE
729 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
730 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000731 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500732 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000733 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700734 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier ip_proto, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000735 return err;
736 }
737 return flow_cfg.data.classifier.ip_proto;
738 case CLASSIFIER_SRC_PORT:
739 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500740 #ifdef TEST_MODE
741 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
742 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000743 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500744 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000745 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700746 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier src_port, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000747 return err;
748 }
749 return flow_cfg.data.classifier.src_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400750 case CLASSIFIER_DST_PORT:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000751 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500752 #ifdef TEST_MODE
753 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
754 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000755 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500756 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000757 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700758 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier dst_port, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000759 return err;
760 }
761 return flow_cfg.data.classifier.dst_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400762 case CLASSIFIER_PKT_TAG_TYPE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000763 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500764 #ifdef TEST_MODE
765 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
766 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000767 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500768 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000769 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700770 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier pkt_tag_type, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000771 return err;
772 }
773 return flow_cfg.data.classifier.pkt_tag_type;
774 case EGRESS_QOS_TYPE:
775 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500776 #ifdef TEST_MODE
777 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
778 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000779 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500780 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000781 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700782 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos type, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000783 return err;
784 }
785 return flow_cfg.data.egress_qos.type;
786 case EGRESS_QOS_QUEUE_ID:
787 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500788 #ifdef TEST_MODE
789 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
790 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000791 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500792 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000793 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700794 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 +0000795 return err;
796 }
797 switch (flow_cfg.data.egress_qos.type) {
798 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE:
799 return flow_cfg.data.egress_qos.u.fixed_queue.queue_id;
800 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE:
801 return flow_cfg.data.egress_qos.u.tc_to_queue.tc_to_queue_id;
802 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC:
803 return flow_cfg.data.egress_qos.u.pbit_to_tc.tc_to_queue_id;
804 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE:
805 return flow_cfg.data.egress_qos.u.priority_to_queue.tm_q_set_id;
806 case BCMOLT_EGRESS_QOS_TYPE_NONE:
807 default:
808 return -1;
809 }
810 case EGRESS_QOS_TM_SCHED_ID:
811 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500812 #ifdef TEST_MODE
813 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
814 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000815 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500816 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000817 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700818 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos tm_sched_id, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000819 return err;
820 }
821 return flow_cfg.data.egress_qos.tm_sched.id;
822 case ACTION_CMDS_BITMASK:
823 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500824 #ifdef TEST_MODE
825 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
826 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000827 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500828 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000829 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700830 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action cmds_bitmask, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000831 return err;
832 }
833 return flow_cfg.data.action.cmds_bitmask;
834 case ACTION_O_VID:
835 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500836 #ifdef TEST_MODE
837 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
838 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000839 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500840 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000841 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700842 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action o_vid, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000843 return err;
844 }
845 return flow_cfg.data.action.o_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400846 case ACTION_O_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000847 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500848 #ifdef TEST_MODE
849 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
850 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000851 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500852 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000853 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700854 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action o_pbits, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000855 return err;
856 }
857 return flow_cfg.data.action.o_pbits;
858 case ACTION_I_VID:
859 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500860 #ifdef TEST_MODE
861 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
862 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000863 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500864 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000865 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700866 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action i_vid, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000867 return err;
868 }
869 return flow_cfg.data.action.i_vid;
870 case ACTION_I_PBITS:
871 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500872 #ifdef TEST_MODE
873 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
874 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000875 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500876 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000877 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700878 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action i_pbits, err = %s (%d)\n",flow_cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000879 return err;
880 }
881 return flow_cfg.data.action.i_pbits;
882 case STATE:
883 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, state);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500884 #ifdef TEST_MODE
885 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
886 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000887 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500888 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000889 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700890 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 +0000891 return err;
892 }
893 return flow_cfg.data.state;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000894 case GROUP_ID:
895 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, group_id);
896 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
897 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -0700898 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 +0000899 return err;
900 }
901 return flow_cfg.data.group_id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000902 default:
903 return BCM_ERR_INTERNAL;
904 }
905
906 return err;
907}
908
909Status EnablePonIf_(uint32_t intf_id) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400910 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000911 bcmolt_pon_interface_cfg interface_obj;
912 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
913 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
914 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530915 bcmolt_status los_status;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000916
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530917 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000918 if (err == BCM_ERR_OK) {
919 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800920 OPENOLT_LOG(WARNING, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000921 return Status::OK;
922 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400923 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000924 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
925 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
926 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
927 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.interval, 5000);
928 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.onu_post_discovery_mode,
Girish Gowdra24297032020-03-23 12:32:37 -0700929 BCMOLT_ONU_POST_DISCOVERY_MODE_NONE);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000930 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.los, true);
931 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.onu_alarms, true);
932 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.tiwi, true);
933 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.ack_timeout, true);
934 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.sfi, true);
935 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.loki, true);
Burak Gurdag5e587792020-05-06 14:58:02 +0000936
937 // On GPON, power level mode is not set to its default value (i.e. 0) as documented in Broadcom documentation.
938 // Instead, it is set to 2 which means -6 dbM attenuation. Therefore, we explicitly set it to the default value below.
Arthur Syu094df162022-04-21 17:50:06 +0800939 std::string intf_technology = intf_technologies[intf_id];
940 if (intf_technology == "GPON") {
Burak Gurdag5e587792020-05-06 14:58:02 +0000941 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.pls_maximum_allocation_size, BCMOLT_PON_POWER_LEVEL_PLS_MAXIMUM_ALLOCATION_SIZE_DEFAULT);
942 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.mode, BCMOLT_PON_POWER_LEVEL_MODE_DEFAULT);
943 }
944
kesavandc1f2db92020-08-31 15:32:06 +0530945 //Enable AES Encryption
946 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.key_exchange, BCMOLT_CONTROL_STATE_ENABLE);
947 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.authentication, BCMOLT_CONTROL_STATE_ENABLE);
948 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.fail_due_to_authentication_failure, BCMOLT_CONTROL_STATE_ENABLE);
949
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000950 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
951 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
952
953 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
954 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500955 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 +0000956 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
957 }
958 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
959 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500960 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 +0000961 return bcm_to_grpc_err(err, "Failed to enable PON interface");
962 }
963 else {
964 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
965 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
966 CreateDefaultSched(intf_id, downstream);
967 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400968 }
969
970 return Status::OK;
971}
972
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500973Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000974 bcmos_errno err;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400975 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000976 bcmolt_device_key dev_key = { };
977 bcmolt_olt_cfg olt_cfg = { };
978 bcmolt_olt_key olt_key = { };
979 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
980 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500981
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000982 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
983 topo.topology_maps.arr = &topo_map[0];
984 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
985 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
986 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400987 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000988 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400989 #ifdef TEST_MODE
990 // It is impossible to mock the setting of olt_cfg.data.bal_state because
991 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
992 // set the olt_cfg.data.topology. So a new stub function is created and address
993 // of olt_cfg is passed. This is one-of case where we need to test add specific
994 // code in production code.
995 err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
996 #else
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000997 err = bcmolt_cfg_get_mult_retry(dev_id, &olt_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400998 #endif
999 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001000 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 +00001001 return bcm_to_grpc_err(err, "cfg: Failed to query OLT topology");
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001002 }
1003
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001004 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
1005 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001006
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001007 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
1008 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001009 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001010
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001011 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
1012 num_of_nni_ports,
1013 num_of_pon_ports,
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001014 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001015
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001016 uint32_t num_failed_cfg_gets = 0;
Jason Huang09b73ea2020-01-08 17:52:05 +08001017 static std::string openolt_version = firmware_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001018 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
1019 dev_key.device_id = devid;
1020 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
1021 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
1022 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
1023 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001024 err = bcmolt_cfg_get_mult_retry(dev_id, &dev_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001025 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001026 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 +00001027 num_failed_cfg_gets++;
1028 continue;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001029 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001030
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001031 std::string bal_version;
1032 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
1033 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
1034 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
Jason Huang09b73ea2020-01-08 17:52:05 +08001035 firmware_version = "BAL." + bal_version + "__" + openolt_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001036
1037 switch(dev_cfg.data.system_mode) {
1038 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
1039 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
1040 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
1041 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
1042 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
1043 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
1044 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
1045 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
1046 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
1047 case 20: board_technology = MIXED_TECH; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,MIXED_TECH); break;
Arthur Syu094df162022-04-21 17:50:06 +08001048 case 38:
1049 board_technology = "XGS-PON";
1050 FILL_ARRAY2(intf_technologies,devid*16,(devid+1)*16,"XGS-PON");
1051 FILL_ARRAY2(intf_technologies,devid*16+1,(devid+1)*16+1,"GPON");
1052 break;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001053 }
1054
1055 switch(dev_cfg.data.chip_family) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001056 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X: chip_family = "Maple"; break;
1057 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X: chip_family = "Aspen"; break;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001058 }
1059
Jason Huang09b73ea2020-01-08 17:52:05 +08001060 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s, family: %s, board_technology: %s\n",
1061 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 +00001062
1063 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001064 }
1065
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001066 /* 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 +00001067 only the devices that retured success*/
1068 if (num_failed_cfg_gets == BCM_MAX_DEVS_PER_LINE_CARD) {
1069 OPENOLT_LOG(ERROR, openolt_log_id, "device: Query of all the devices failed\n");
1070 return bcm_to_grpc_err(err, "device: All devices failed query");
1071 }
1072
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001073 return Status::OK;
1074}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001075
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001076Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001077 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001078 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
1079 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
1080 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001081
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001082 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001083 if (err == BCM_ERR_OK) {
1084 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001085 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001086 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1087 CreateDefaultSched(intf_id, upstream);
1088 CreateDefaultQueue(intf_id, upstream);
1089 return Status::OK;
1090 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1091 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
1092 return Status::OK;
1093 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001094 }
1095
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001096 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
1097 if (set_state) {
1098 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1099 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1100 } else {
1101 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1102 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1103 }
1104 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
1105 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001106 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err = %s\n",
1107 (set_state)?"enable":"disable", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001108 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
1109 }
1110 else {
1111 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
1112 if (set_state) {
1113 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1114 CreateDefaultSched(intf_id, upstream);
1115 CreateDefaultQueue(intf_id, upstream);
1116 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001117 }
1118
1119 return Status::OK;
1120}
1121
Elia Battiston869a5de2022-02-08 11:40:58 +01001122uint32_t GetNniSpeed_(uint32_t intf_id) {
1123 bcmos_errno err = BCM_ERR_OK;
1124
1125 uint32_t speed;
1126 err = get_nni_interface_speed((bcmolt_interface)intf_id, &speed);
1127 if (err != BCM_ERR_OK) {
1128 OPENOLT_LOG(WARNING, openolt_log_id, "Failed to read speed of NNI interface: %d\n", intf_id);
1129 return 0; //This will cause the adapter to use the default speed value
1130 }
1131
1132 return speed;
1133}
1134
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001135Status DisablePonIf_(uint32_t intf_id) {
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001136 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001137 bcmolt_pon_interface_cfg interface_obj;
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001138 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1139 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001140
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001141 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
Girish Gowdrae1db2952021-05-04 00:16:54 -07001142 BCMOLT_MSG_FIELD_GET(&interface_obj, state);
1143
1144 err = bcmolt_cfg_get(dev_id, &interface_obj.hdr);
1145 if (err != BCM_ERR_OK) {
1146 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);
1147 return bcm_to_grpc_err(err, "Failed to fetch pon port state");
1148 }
1149 if (interface_obj.data.state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1150 OPENOLT_LOG(INFO, openolt_log_id, "PON Interface already inactive, PON interface %d\n", intf_id);
1151 return Status::OK;
1152 }
1153
1154 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001155 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1156 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_DISABLE);
1157
1158 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1159 if (err != BCM_ERR_OK) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07001160 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 -05001161 return bcm_to_grpc_err(err, "Failed to disable discovery of onu");
1162 }
1163
1164 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1165 operation, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1166
1167 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1168 if (err != BCM_ERR_OK) {
1169 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 -04001170 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001171 }
1172
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001173 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled PON interface: %d\n", intf_id);
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001174 return Status::OK;
1175}
1176
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001177Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
kesavandc1f2db92020-08-31 15:32:06 +05301178 const char *vendor_id, const char *vendor_specific, uint32_t pir, bool omcc_encryption_mode) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001179 bcmos_errno err = BCM_ERR_OK;
1180 bcmolt_onu_cfg onu_cfg;
1181 bcmolt_onu_key onu_key;
1182 bcmolt_serial_number serial_number; /**< ONU serial number */
1183 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001184
Girish Gowdra24297032020-03-23 12:32:37 -07001185 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1186 bcmolt_onu_state onu_state;
1187
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001188 onu_key.onu_id = onu_id;
1189 onu_key.pon_ni = intf_id;
1190 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1191 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Girish Gowdra24297032020-03-23 12:32:37 -07001192#ifdef TEST_MODE
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001193 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1194 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1195 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1196 // of onu_cfg is passed. This is one-of case where we need to add test specific
1197 // code in production code.
1198 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Girish Gowdra24297032020-03-23 12:32:37 -07001199#else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001200 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Girish Gowdra24297032020-03-23 12:32:37 -07001201#endif
1202 OPENOLT_LOG(INFO, openolt_log_id, "Activate ONU : old state = %d, current state = %d\n",
1203 onu_cfg.data.onu_old_state, onu_cfg.data.onu_state);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001204 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001205 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) {
1206 OPENOLT_LOG(INFO, openolt_log_id, "ONU is already in ACTIVE state, \
1207not processing this request for pon_intf=%d onu_id=%d\n", intf_id, onu_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001208 return Status::OK;
Girish Gowdra24297032020-03-23 12:32:37 -07001209 } else if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_NOT_CONFIGURED &&
1210 onu_cfg.data.onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1211 // We need the ONU to be in NOT_CONFIGURED or INACTIVE state to further process the request
1212 OPENOLT_LOG(ERROR, openolt_log_id, "ONU in an invalid state to process the request, \
1213state=%d pon_intf=%d onu_id=%d\n", onu_cfg.data.onu_state, intf_id, onu_id);
1214 return bcm_to_grpc_err(err, "Failed to activate ONU, invalid ONU state");
1215 }
1216 } else {
1217 // This should never happen. BAL GET should succeed for non-existant ONUs too. The state of such ONUs will be NOT_CONFIGURED
1218 OPENOLT_LOG(ERROR, openolt_log_id, "ONU state query failed pon_intf=%d onu_id=%d\n", intf_id, onu_id);
1219 return bcm_to_grpc_err(err, "onu get failed");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001220 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001221
Girish Gowdra24297032020-03-23 12:32:37 -07001222 // If the ONU is not configured at all we need to first configure it
1223 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_NOT_CONFIGURED) {
1224 OPENOLT_LOG(INFO, openolt_log_id, "Configuring ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001225vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Girish Gowdra24297032020-03-23 12:32:37 -07001226 vendor_specific_to_str(vendor_specific).c_str(), pir);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001227
Girish Gowdra24297032020-03-23 12:32:37 -07001228 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1229 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1230 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1231 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1232 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1233 /*set burst and data profiles to fec disabled*/
Arthur Syu094df162022-04-21 17:50:06 +08001234 std::string intf_technology = intf_technologies[intf_id];
1235 if (intf_technology == "XGS-PON") {
Girish Gowdra24297032020-03-23 12:32:37 -07001236 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1237 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
Arthur Syu094df162022-04-21 17:50:06 +08001238 } else if (intf_technology == "GPON") {
Girish Gowdra24297032020-03-23 12:32:37 -07001239 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1240 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1241 }
1242 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1243 if (err != BCM_ERR_OK) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07001244 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 -07001245 return bcm_to_grpc_err(err, "Failed to configure ONU");
1246 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001247 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001248
Burak Gurdaga0523592021-02-24 15:17:47 +00001249// TODO: MOVE THIS TO A NEW METHOD
kesavandc1f2db92020-08-31 15:32:06 +05301250 if (omcc_encryption_mode == true) {
1251 // set the encryption mode for omci port id
1252 bcmolt_itupon_gem_cfg gem_cfg;
1253 bcmolt_itupon_gem_key key = {};
1254 bcmolt_gem_port_configuration configuration = {};
1255 key.pon_ni = intf_id;
1256 key.gem_port_id = onu_id;
1257 bcmolt_control_state encryption_mode;
1258 encryption_mode = BCMOLT_CONTROL_STATE_ENABLE;
1259 BCMOLT_CFG_INIT(&gem_cfg, itupon_gem, key);
1260 BCMOLT_FIELD_SET(&gem_cfg.data, itupon_gem_cfg_data, encryption_mode, encryption_mode);
1261 err = bcmolt_cfg_set(dev_id, &gem_cfg.hdr);
1262 if(err != BCM_ERR_OK) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07001263 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 +05301264 return bcm_to_grpc_err(err, "Access_Control set ITU PON OMCI Gem port failed");
1265 }
1266 }
Girish Gowdra24297032020-03-23 12:32:37 -07001267 // Now that the ONU is configured, move the ONU to ACTIVE state
1268 memset(&onu_cfg, 0, sizeof(bcmolt_onu_cfg));
1269 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1270 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1271 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
1272 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
1273 onu_state, BCMOLT_ONU_OPERATION_ACTIVE);
1274 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001275 if (err != BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001276 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 +00001277 return bcm_to_grpc_err(err, "Failed to activate ONU");
1278 }
Girish Gowdra24297032020-03-23 12:32:37 -07001279 // ONU will eventually get activated after we have submitted the operation request. The adapter will receive an asynchronous
1280 // ONU_ACTIVATION_COMPLETED_INDICATION
1281
1282 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 +00001283
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001284 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001285}
1286
Jonathan Davis70c21812018-07-19 15:32:10 -04001287Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1288 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001289 bcmos_errno err = BCM_ERR_OK;
1290 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1291 bcmolt_onu_cfg onu_cfg;
1292 bcmolt_onu_key onu_key; /**< Object key. */
1293 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001294
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001295 onu_key.onu_id = onu_id;
1296 onu_key.pon_ni = intf_id;
1297 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1298 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1299 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301300 onu_state = onu_cfg.data.onu_state;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001301 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001302 switch (onu_state) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001303 case BCMOLT_ONU_STATE_ACTIVE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001304 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001305 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001306 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1307 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1308 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001309 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 +00001310 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1311 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301312 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 +00001313 break;
1314 }
Girish Gowdra72cbee92021-11-05 15:16:18 -07001315 } else {
1316 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to deactivate ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
1317 return bcm_to_grpc_err(err, "Failed to get onu config");
Jonathan Davis70c21812018-07-19 15:32:10 -04001318 }
1319
1320 return Status::OK;
1321}
1322
1323Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001324 const char *vendor_id, const char *vendor_specific) {
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301325 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301326 bcmolt_onu_state onu_state;
Girish Gowdra72cbee92021-11-05 15:16:18 -07001327 Status st;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001328
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001329 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 -05001330 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1331
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001332 // Need to deactivate before removing it (BAL rules)
Girish Gowdra72cbee92021-11-05 15:16:18 -07001333 st = DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
1334 if (st.error_code() != grpc::StatusCode::OK) {
1335 return st;
1336 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301337
Girish Gowdra72cbee92021-11-05 15:16:18 -07001338 err = get_onu_state((bcmolt_interface)intf_id, onu_id, &onu_state);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301339 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001340 if (onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1341 OPENOLT_LOG(INFO, openolt_log_id, "waiting for onu deactivate complete response: intf_id=%d, onu_id=%d\n",
1342 intf_id, onu_id);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301343 err = wait_for_onu_deactivate_complete(intf_id, onu_id);
1344 if (err) {
1345 OPENOLT_LOG(ERROR, openolt_log_id, "failed to delete onu intf_id %d, onu_id %d\n",
1346 intf_id, onu_id);
1347 return bcm_to_grpc_err(err, "Failed to delete ONU");
1348 }
1349 }
Girish Gowdra24297032020-03-23 12:32:37 -07001350 else {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301351 OPENOLT_LOG(INFO, openolt_log_id, "Onu is Inactive, onu_id: %d, not waiting for onu deactivate complete response\n",
1352 intf_id);
1353 }
1354 }
1355 else {
1356 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch Onu status, onu_id = %d, intf_id = %d, err = %s\n",
1357 onu_id, intf_id, bcmos_strerror(err));
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301358 return bcm_to_grpc_err(err, "Failed to delete ONU");
1359 }
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001360
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001361 bcmolt_onu_cfg cfg_obj;
1362 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001363
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001364 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 -04001365 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001366
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001367 key.onu_id = onu_id;
1368 key.pon_ni = intf_id;
1369 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001370
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301371 err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001372 if (err != BCM_ERR_OK)
1373 {
Girish Gowdra72cbee92021-11-05 15:16:18 -07001374 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 -04001375 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1376 }
1377
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301378 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 +00001379 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001380}
1381
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001382#define MAX_CHAR_LENGTH 20
1383#define MAX_OMCI_MSG_LENGTH 44
1384Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001385 bcmolt_bin_str buf = {};
1386 bcmolt_onu_cpu_packets omci_cpu_packets;
1387 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001388
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001389 key.pon_ni = intf_id;
1390 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001391
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001392 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1393 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1394 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001395
1396 // ???
1397 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1398 buf.len = MAX_OMCI_MSG_LENGTH;
1399 } else {
1400 buf.len = pkt.size()/2;
1401 }
1402
1403 /* Send the OMCI packet using the BAL remote proxy API */
1404 uint16_t idx1 = 0;
1405 uint16_t idx2 = 0;
1406 uint8_t arraySend[buf.len];
1407 char str1[MAX_CHAR_LENGTH];
1408 char str2[MAX_CHAR_LENGTH];
1409 memset(&arraySend, 0, buf.len);
1410
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001411 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1412 sprintf(str1,"%c", pkt[idx1]);
1413 sprintf(str2,"%c", pkt[++idx1]);
1414 strcat(str1,str2);
1415 arraySend[idx2] = strtol(str1, NULL, 16);
1416 }
1417
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001418 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1419 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001420
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001421 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1422 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1423 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001424
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001425 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001426 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001427 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 +00001428 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001429 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001430 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 -05001431 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001432 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001433 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001434
1435 return Status::OK;
1436}
1437
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001438Status 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 +00001439 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1440 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1441 bcmolt_bin_str buf = {};
1442 bcmolt_gem_port_id gem_port_id_array[1];
1443 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001444
Craig Lutgen967a1d02018-11-27 10:41:51 -06001445 if (port_no > 0) {
1446 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001447 if (gemport_id == 0) {
1448 bcmos_fastlock_lock(&data_lock);
1449 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1450 // Pick any flow that is mapped with the same port_no.
1451 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1452 if (it != port_to_flows.end() && !it->second.empty()) {
1453 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1454 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1455 if (fit != flowid_to_gemport.end()) {
1456 found = true;
1457 gemport_id = fit->second;
1458 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001459 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001460 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001461
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001462 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001463 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 -08001464 onu_id, port_no, intf_id);
1465 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1466 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001467 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 -08001468 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001469 }
1470
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001471 gem_port_id_array[0] = gemport_id;
1472 gem_port_list.len = 1;
1473 gem_port_list.arr = gem_port_id_array;
1474 buf.len = pkt.size();
1475 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1476 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1477
1478 /* init the API struct */
1479 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1480 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1481 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1482 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1483 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1484
1485 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1486 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1487
1488 /* call API */
1489 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001490 }
1491 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001492 //TODO: Port No is 0, it is coming sender requirement.
1493 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1494 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001495 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001496 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001497
1498 return Status::OK;
1499}
1500
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001501Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001502 bcmolt_flow_key key = {}; /* declare key */
1503 bcmolt_bin_str buffer = {};
1504 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001505
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001506 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
Girish Gowdra252f4972020-09-07 21:24:01 -07001507 bcmolt_flow_id flow_id = INVALID_FLOW_ID;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001508
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001509 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1510 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1511 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1512 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1513 key.flow_id = flow_id;
1514 else {
Jason Huang09b73ea2020-01-08 17:52:05 +08001515 if (flow_id_counters) {
1516 std::map<flow_pair, int>::iterator it;
1517 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1518 int flow_index = it->first.first;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001519 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1520 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1521 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1522 key.flow_id = flow_index;
1523 break;
1524 }
1525 }
1526 }
1527 else {
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001528 OPENOLT_LOG(ERROR, openolt_log_id, "no flow id found for uplink packetout\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001529 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1530 }
1531 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001532
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001533 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001534
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001535 /* Initialize the API struct. */
1536 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001537
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001538 buffer.len = pkt.size();
1539 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1540 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1541 if (buffer.arr == NULL) {
1542 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1543 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1544 }
1545 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1546
1547 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1548 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001549 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 -05001550 return bcm_to_grpc_err(BCM_ERR_SYSCALL_ERR, "Error sending packets via nni port");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001551 } else {
1552 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1553 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001554
1555 return Status::OK;
1556}
Girish Gowdra252f4972020-09-07 21:24:01 -07001557
Burak Gurdaga0523592021-02-24 15:17:47 +00001558bool get_aes_flag_for_gem_port(const google::protobuf::Map<unsigned int, bool> &gemport_to_aes, uint32_t gemport_id) {
1559 bool aes_flag = false;
1560 for (google::protobuf::Map<unsigned int, bool>::const_iterator it=gemport_to_aes.begin(); it!=gemport_to_aes.end(); it++) {
1561 if (it->first == gemport_id) {
1562 aes_flag = it->second;
1563 break;
1564 }
1565 }
1566 return aes_flag;
1567}
1568
Girish Gowdra252f4972020-09-07 21:24:01 -07001569Status FlowAddWrapper_(const ::openolt::Flow* request) {
1570
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001571 Status st = Status::OK;
Girish Gowdra252f4972020-09-07 21:24:01 -07001572 int32_t access_intf_id = request->access_intf_id();
1573 int32_t onu_id = request->onu_id();
1574 int32_t uni_id = request->uni_id();
1575 uint32_t port_no = request->port_no();
1576 uint64_t voltha_flow_id = request->flow_id();
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001577 uint64_t symmetric_voltha_flow_id = 0;
Girish Gowdra252f4972020-09-07 21:24:01 -07001578 const std::string flow_type = request->flow_type();
1579 int32_t alloc_id = request->alloc_id();
1580 int32_t network_intf_id = request->network_intf_id();
1581 int32_t gemport_id = request->gemport_id();
1582 const ::openolt::Classifier& classifier = request->classifier();
1583 const ::openolt::Action& action = request->action();
1584 int32_t priority = request->priority();
1585 uint64_t cookie = request->cookie();
1586 int32_t group_id = request->group_id();
1587 uint32_t tech_profile_id = request->tech_profile_id();
1588 bool replicate_flow = request->replicate_flow();
1589 const google::protobuf::Map<unsigned int, unsigned int> &pbit_to_gemport = request->pbit_to_gemport();
Burak Gurdaga0523592021-02-24 15:17:47 +00001590 const google::protobuf::Map<unsigned int, bool> &gemport_to_aes = request->gemport_to_aes();
Girish Gowdra252f4972020-09-07 21:24:01 -07001591 uint16_t flow_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001592 bool enable_encryption;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001593 // When following conditions are ALL met, it qualifies as datapath flow.
1594 // 1. valid access_intf_id, onu_id, uni_id
1595 // 2. Valid tech_profile_id
1596 // 3. flow_type that is not MULTICAST
1597 // 4. Not a trap-to-host flow.
1598 bool datapathFlow = access_intf_id >= 0 && onu_id >= 0 && uni_id >= 0 && tech_profile_id > 0
1599 && flow_type != multicast && !action.cmd().trap_to_host();
1600
1601 if (datapathFlow) {
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08001602 const std::string inverse_flow_type = flow_type == upstream? downstream : upstream;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001603 symmetric_datapath_flow_id_map_key key(access_intf_id, onu_id, uni_id, tech_profile_id, inverse_flow_type);
1604 // Find the onu-uni mapping for the pon-gem key
1605 bcmos_fastlock_lock(&symmetric_datapath_flow_id_lock);
1606 auto it = symmetric_datapath_flow_id_map.find(key);
1607 bcmos_fastlock_unlock(&symmetric_datapath_flow_id_lock, 0);
1608 if (it != symmetric_datapath_flow_id_map.end()) {
1609 symmetric_voltha_flow_id = it->second;
1610 }
1611 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001612
1613 // The intf_id variable defaults to access(PON) interface ID.
1614 // For trap-from-nni flow where access interface ID is not valid , change it to NNI interface ID
1615 // This intf_id identifies the pool from which we get the flow_id
1616 uint32_t intf_id = access_intf_id;
1617 if (onu_id < 1) {
1618 onu_id = 1;
1619 }
1620 if (access_intf_id < 0) {
1621 intf_id = network_intf_id;
1622 }
1623
1624 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)
1625 // This is the case of voltha_flow_id (not symmetric_voltha_flow_id)
1626 if (is_voltha_flow_installed(voltha_flow_id)) {
1627 OPENOLT_LOG(INFO, openolt_log_id, "voltha_flow_id=%lu, already installed\n", voltha_flow_id);
1628 return ::Status(grpc::StatusCode::ALREADY_EXISTS, "voltha-flow-already-installed");
1629 }
1630
Girish Gowdra252f4972020-09-07 21:24:01 -07001631 // This is the case of symmetric_voltha_flow_id
1632 // If symmetric_voltha_flow_id is available and valid in the Flow message,
1633 // check if it is installed, and use the corresponding device_flow_id
1634 if (symmetric_voltha_flow_id > 0 && is_voltha_flow_installed(symmetric_voltha_flow_id)) { // symmetric flow found
1635 OPENOLT_LOG(INFO, openolt_log_id, "symmetric flow and the symmetric flow is installed\n");
1636 const device_flow_params *dev_fl_symm_params;
1637 dev_fl_symm_params = get_device_flow_params(symmetric_voltha_flow_id);
1638 if (dev_fl_symm_params == NULL) {
1639 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)
1640 return ::Status(grpc::StatusCode::INTERNAL, "symmetric-flow-details-not-found");
1641 }
1642
1643 if (!replicate_flow) { // No flow replication
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001644 flow_id = dev_fl_symm_params[0].flow_id;
1645 gemport_id = dev_fl_symm_params[0].gemport_id; // overwrite the gemport with symmetric flow gemport
1646 // Should be same as what is coming in this request.
1647 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
1648 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1649 cl.set_o_pbits(dev_fl_symm_params[0].pbit);
1650 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1651 flow_type, alloc_id, network_intf_id, gemport_id, cl,
1652 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
1653 if (st.error_code() != grpc::StatusCode::OK && st.error_code() != grpc::StatusCode::ALREADY_EXISTS) {
1654 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 -07001655 free_flow_id(flow_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001656 return st;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001657 }
1658
1659 device_flow dev_fl;
1660 dev_fl.is_flow_replicated = false;
1661 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1662 dev_fl.voltha_flow_id = voltha_flow_id;
Girish Gowdra72bb4652022-01-18 17:04:30 -08001663 dev_fl.flow_type = flow_type;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001664 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params));
1665 // update voltha flow to cache
1666 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
Girish Gowdra252f4972020-09-07 21:24:01 -07001667 } else { // Flow to be replicated
1668 OPENOLT_LOG(INFO, openolt_log_id,"symmetric flow and replication is needed\n");
1669 for (uint8_t i=0; i<NUMBER_OF_REPLICATED_FLOWS; i++) {
1670 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1671 flow_id = dev_fl_symm_params[i].flow_id;
1672 gemport_id = dev_fl_symm_params[i].gemport_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001673 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001674 cl.set_o_pbits(dev_fl_symm_params[i].pbit);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001675 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdrade65ab42020-12-17 23:08:43 -08001676 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001677 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001678 if (st.error_code() != grpc::StatusCode::OK && st.error_code() != grpc::StatusCode::ALREADY_EXISTS) {
1679 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);
1680 // On failure remove any successfully replicated flows installed so far for the voltha_flow_id
1681 if (i > 0) {
1682 for (int8_t j = i-1; j >= 0; j--) {
1683 flow_id = dev_fl_symm_params[j].flow_id;
1684 FlowRemove_(flow_id, flow_type);
1685 }
1686 }
Girish Gowdra72cbee92021-11-05 15:16:18 -07001687 // Note: We should not free the flow_ids here because the symmetric flow is already using that flow id.
1688 // 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 -07001689 return st;
1690 }
1691 }
1692 device_flow dev_fl;
1693 dev_fl.is_flow_replicated = true;
1694 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1695 dev_fl.voltha_flow_id = voltha_flow_id;
Girish Gowdra72bb4652022-01-18 17:04:30 -08001696 dev_fl.flow_type = flow_type;
Girish Gowdra252f4972020-09-07 21:24:01 -07001697 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params)*NUMBER_OF_REPLICATED_FLOWS);
1698 // update voltha flow to cache
1699 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1700 }
1701 } else { // No symmetric flow found
1702 if (!replicate_flow) { // No flow replication
1703 OPENOLT_LOG(INFO, openolt_log_id, "not a symmetric flow and replication is not needed\n");
1704 flow_id = get_flow_id();
1705 if (flow_id == INVALID_FLOW_ID) {
1706 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocated flow id for voltha-flow-id=%lu\n", voltha_flow_id);
1707 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1708 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001709 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001710 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001711 flow_type, alloc_id, network_intf_id, gemport_id, classifier,
Burak Gurdaga0523592021-02-24 15:17:47 +00001712 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001713 if (st.error_code() == grpc::StatusCode::OK) {
1714 device_flow dev_fl;
1715 dev_fl.is_flow_replicated = false;
1716 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // Invalid
1717 dev_fl.voltha_flow_id = voltha_flow_id;
Girish Gowdra72bb4652022-01-18 17:04:30 -08001718 dev_fl.flow_type = flow_type;
Girish Gowdra252f4972020-09-07 21:24:01 -07001719 dev_fl.params[0].flow_id = flow_id;
1720 dev_fl.params[0].gemport_id = gemport_id;
1721 dev_fl.params[0].pbit = classifier.o_pbits();
1722 // update voltha flow to cache
1723 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1724 } else {
1725 // Free the flow id on failure
1726 free_flow_id(flow_id);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001727 return st;
Girish Gowdra252f4972020-09-07 21:24:01 -07001728 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001729 } else { // Flow to be replicated
1730 OPENOLT_LOG(INFO, openolt_log_id,"not a symmetric flow and replication is needed\n");
1731 if (pbit_to_gemport.size() != NUMBER_OF_PBITS) {
1732 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pbit-to-gemport map size=%lu", pbit_to_gemport.size())
1733 return ::Status(grpc::StatusCode::OUT_OF_RANGE, "pbit-to-gemport-map-len-invalid-for-flow-replication");
1734 }
1735 uint16_t flow_ids[NUMBER_OF_REPLICATED_FLOWS];
1736 device_flow dev_fl;
1737 if (get_flow_ids(NUMBER_OF_REPLICATED_FLOWS, flow_ids)) {
1738 uint8_t cnt = 0;
1739 dev_fl.is_flow_replicated = true;
1740 dev_fl.voltha_flow_id = voltha_flow_id;
1741 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // invalid
Girish Gowdra72bb4652022-01-18 17:04:30 -08001742 dev_fl.flow_type = flow_type;
Girish Gowdra252f4972020-09-07 21:24:01 -07001743 for (google::protobuf::Map<unsigned int, unsigned int>::const_iterator it=pbit_to_gemport.begin(); it!=pbit_to_gemport.end(); it++) {
1744 dev_fl.params[cnt].flow_id = flow_ids[cnt];
1745 dev_fl.params[cnt].pbit = it->first;
1746 dev_fl.params[cnt].gemport_id = it->second;
1747
1748 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1749 flow_id = dev_fl.params[cnt].flow_id;
1750 gemport_id = dev_fl.params[cnt].gemport_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001751 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001752 cl.set_o_pbits(dev_fl.params[cnt].pbit);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001753 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001754 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001755 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001756 if (st.error_code() != grpc::StatusCode::OK) {
1757 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);
1758 // Remove any successfully replicated flows installed so far for the voltha_flow_id
1759 if (cnt > 0) {
1760 for (int8_t j = cnt-1; j >= 0; j--) {
1761 flow_id = dev_fl.params[j].flow_id;
1762 FlowRemove_(flow_id, flow_type);
1763 }
1764 }
1765 // Free up all the flow IDs on failure
1766 free_flow_ids(NUMBER_OF_REPLICATED_FLOWS, flow_ids);
1767 return st;
1768 }
1769 cnt++;
1770 }
1771 // On successful flow replication update voltha-flow-id to device-flow map to cache
1772 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1773 } else {
1774 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocate flow ids for replication voltha-flow-id=%lu\n", voltha_flow_id);
1775 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1776 }
1777 }
1778 }
1779
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001780 if (datapathFlow) {
1781 // Create the pon-gem to onu-uni mapping
1782 symmetric_datapath_flow_id_map_key key(access_intf_id, onu_id, uni_id, tech_profile_id, flow_type);
1783 bcmos_fastlock_lock(&symmetric_datapath_flow_id_lock);
1784 symmetric_datapath_flow_id_map[key] = voltha_flow_id;
1785 bcmos_fastlock_unlock(&symmetric_datapath_flow_id_lock, 0);
1786 }
1787
1788 return st;
Girish Gowdra252f4972020-09-07 21:24:01 -07001789}
1790
1791
Craig Lutgen967a1d02018-11-27 10:41:51 -06001792Status 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 +00001793 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001794 int32_t alloc_id, int32_t network_intf_id,
1795 int32_t gemport_id, const ::openolt::Classifier& classifier,
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001796 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie,
Burak Gurdaga0523592021-02-24 15:17:47 +00001797 int32_t group_id, uint32_t tech_profile_id, bool aes_enabled) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001798 bcmolt_flow_cfg cfg;
1799 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001800 int32_t o_vid = -1;
1801 bool single_tag = false;
1802 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001803 bcmolt_classifier c_val = { };
1804 bcmolt_action a_val = { };
1805 bcmolt_tm_queue_ref tm_val = { };
1806 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05001807 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001808
Jason Huang09b73ea2020-01-08 17:52:05 +08001809 OPENOLT_LOG(INFO, openolt_log_id, "flow add received for flow_id=%u, flow_type=%s\n", flow_id, flow_type.c_str());
1810
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001811 key.flow_id = flow_id;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08001812 if (flow_type == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001813 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08001814 } else if (flow_type == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001815 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08001816 } else if (flow_type == multicast) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001817 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001818 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001819 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001820 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001821 }
1822
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001823 BCMOLT_CFG_INIT(&cfg, flow, key);
1824 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001825
Jason Huang09b73ea2020-01-08 17:52:05 +08001826 if (action.cmd().trap_to_host()) {
Girish Gowdra1935e6a2020-10-31 21:48:22 -07001827 Status resp = handle_acl_rule_install(onu_id, flow_id, gemport_id, flow_type, access_intf_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001828 network_intf_id, classifier);
Jason Huang09b73ea2020-01-08 17:52:05 +08001829 return resp;
1830 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001831
1832 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1833
1834 if (access_intf_id >= 0 && network_intf_id >= 0) {
1835 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1836 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1837 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08001838 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1839 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001840 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1841 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1842 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1843 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1844 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001845 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001846 } else {
1847 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
1848 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001849 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001850
Burak Gurdaga0523592021-02-24 15:17:47 +00001851 if (onu_id >= ONU_ID_START) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001852 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
1853 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001854 if (gemport_id >= GEM_PORT_ID_START) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001855 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
1856 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001857 if (gemport_id >= GEM_PORT_ID_START && port_no != 0) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001858 bcmos_fastlock_lock(&data_lock);
1859 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
1860 port_to_flows[port_no].insert(key.flow_id);
1861 flowid_to_gemport[key.flow_id] = gemport_id;
1862 }
1863 else
1864 {
1865 flowid_to_port[key.flow_id] = port_no;
1866 }
1867 bcmos_fastlock_unlock(&data_lock, 0);
1868 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001869
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001870 if (priority_value >= 0) {
1871 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
1872 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301873
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001874 } else { // MULTICAST FLOW
1875 if (group_id >= 0) {
1876 BCMOLT_MSG_FIELD_SET(&cfg, group_id, group_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001877 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001878 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1879 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001880 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001881
1882 {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001883 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001884 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001885 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
1886 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001887 }
1888
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001889 if (classifier.dst_mac().size() > 0) {
1890 bcmos_mac_address d_mac = {};
1891 bcmos_mac_address_init(&d_mac);
1892 memcpy(d_mac.u8, classifier.dst_mac().data(), sizeof(d_mac.u8));
1893 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_mac %02x:%02x:%02x:%02x:%02x:%02x\n", d_mac.u8[0],
1894 d_mac.u8[1], d_mac.u8[2], d_mac.u8[3], d_mac.u8[4], d_mac.u8[5]);
1895 BCMOLT_FIELD_SET(&c_val, classifier, dst_mac, d_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001896 }
1897
Girish Gowdraf83e17a2022-02-16 16:27:00 -08001898 if (classifier.src_mac().size() > 0) {
1899 bcmos_mac_address s_mac = {};
1900 bcmos_mac_address_init(&s_mac);
1901 memcpy(s_mac.u8, classifier.src_mac().data(), sizeof(s_mac.u8));
1902 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_mac %02x:%02x:%02x:%02x:%02x:%02x\n", s_mac.u8[0],
1903 s_mac.u8[1], s_mac.u8[2], s_mac.u8[3], s_mac.u8[4], s_mac.u8[5]);
1904 BCMOLT_FIELD_SET(&c_val, classifier, src_mac, s_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001905 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001906
1907 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001908 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
1909 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001910 }
1911
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001912 if (classifier.dst_ip()) {
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08001913 bcmos_ipv4_address d_ip = {};
1914 bcmos_ipv4_address_init(&d_ip);
1915 d_ip.u32 = classifier.dst_ip();
1916 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_ip %04x\n", d_ip.u32);
1917 BCMOLT_FIELD_SET(&c_val, classifier, dst_ip, d_ip);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001918 }
1919
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08001920 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001921 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001922 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001923 }
1924 */
1925
1926 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001927 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
1928 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001929 }
1930
1931 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001932 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
1933 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001934 }
1935
1936 if (!classifier.pkt_tag_type().empty()) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001937 if (classifier.o_vid()) {
1938 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
1939 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
1940 }
1941
1942 if (classifier.i_vid()) {
1943 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
1944 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
1945 }
1946
1947 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
1948 if (classifier.pkt_tag_type().compare("untagged") == 0) {
1949 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
1950 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
1951 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
1952 single_tag = true;
1953
1954 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301955 // OpenOlt adapter will send 0xFF in case of no pbit classification
1956 // If it is any other value (0 to 7), it is for outer pbit classification.
1957 // OpenFlow protocol does not provide inner pbit classification (in case of double tagged packets),
1958 // and VOLTHA has not used any workaround to solve this problem (for ex: use metadata field).
1959 // Also there exists no use case for i-pbit classification, so we can safely ignore this for now.
1960 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001961 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301962 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001963 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
1964 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001965
Jason Huang09b73ea2020-01-08 17:52:05 +08001966 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301967 // Same comments as in case of "single_tag" packets.
1968 // 0xFF means no pbit classification, otherwise a valid PCP (0 to 7).
1969 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001970 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301971 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001972 }
1973 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001974 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001975 }
1976
Jason Huang09b73ea2020-01-08 17:52:05 +08001977 const ::openolt::ActionCmd& cmd = action.cmd();
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001978
Jason Huang09b73ea2020-01-08 17:52:05 +08001979 if (cmd.add_outer_tag()) {
1980 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
1981 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001982 }
1983
Jason Huang09b73ea2020-01-08 17:52:05 +08001984 if (cmd.remove_outer_tag()) {
1985 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
1986 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
1987 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301988
Girish Gowdraf83e17a2022-02-16 16:27:00 -08001989 if (cmd.translate_outer_tag()) {
1990 OPENOLT_LOG(DEBUG, openolt_log_id, "action translate o_tag\n");
1991 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_XLATE_OUTER_TAG);
1992 }
1993
Jason Huang09b73ea2020-01-08 17:52:05 +08001994 if (action.o_vid()) {
1995 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
1996 o_vid = action.o_vid();
1997 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
1998 }
1999
2000 if (action.o_pbits()) {
2001 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
2002 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
2003 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05302004
Jason Huang09b73ea2020-01-08 17:52:05 +08002005 if (action.i_vid()) {
2006 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
2007 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
2008 }
2009
2010 if (action.i_pbits()) {
2011 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
2012 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
2013 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05302014
Jason Huang09b73ea2020-01-08 17:52:05 +08002015 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
2016
Burak Gurdaga0523592021-02-24 15:17:47 +00002017 if ((access_intf_id >= 0) && (onu_id >= ONU_ID_START)) {
Jason Huang09b73ea2020-01-08 17:52:05 +08002018 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
2019 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002020 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 +00002021
Jason Huang09b73ea2020-01-08 17:52:05 +08002022 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2023 // Queue 0 on DS subscriber scheduler
2024 tm_val.queue_id = 0;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002025
Jason Huang09b73ea2020-01-08 17:52:05 +08002026 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2027 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2028 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002029
Jason Huang09b73ea2020-01-08 17:52:05 +08002030 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2031 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2032 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002033
Jason Huang09b73ea2020-01-08 17:52:05 +08002034 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2035 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
2036 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 +00002037
Jason Huang09b73ea2020-01-08 17:52:05 +08002038 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2039 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2040 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2041 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 +00002042
Jason Huang09b73ea2020-01-08 17:52:05 +08002043 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2044 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2045 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2046 }
2047 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
2048 // NNI Scheduler ID
2049 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2050 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2051 // Queue 0 on NNI scheduler
2052 tm_val.queue_id = 0;
2053 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2054 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2055 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002056
Jason Huang09b73ea2020-01-08 17:52:05 +08002057 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 +00002058 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2059 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2060
Jason Huang09b73ea2020-01-08 17:52:05 +08002061 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2062 /* Fetch TM QMP ID mapped to US NNI scheduler */
2063 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2064 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2065 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2066 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2067 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 +00002068
Jason Huang09b73ea2020-01-08 17:52:05 +08002069 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 +00002070 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2071 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002072 }
Shad Ansari39739bc2018-09-13 21:38:37 +00002073 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302074 } else {
2075 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2076 tm_val.queue_id = 0;
2077
2078 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2079 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2080 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2081
2082 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2083 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
2084 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00002085 }
2086
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002087 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002088
Girish Gowdra252f4972020-09-07 21:24:01 -07002089#ifndef SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002090 // BAL 3.1 supports statistics only for unicast flows.
2091 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
2092 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
2093 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002094#endif // SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002095
Girish Gowdra252f4972020-09-07 21:24:01 -07002096#ifndef SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002097#ifdef FLOW_CHECKER
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002098 //Flow Checker, To avoid duplicate flow.
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002099 if (flow_id_counters != 0) {
2100 bool b_duplicate_flow = false;
Jason Huang09b73ea2020-01-08 17:52:05 +08002101 std::map<flow_pair, int>::iterator it;
2102
2103 for(it = flow_map.begin(); it != flow_map.end(); it++) {
2104 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(it->first.first, it->first.second, ONU_ID)) && \
2105 (key.flow_type == it->first.second) && \
2106 (cfg.data.svc_port_id == get_flow_status(it->first.first, it->first.second, SVC_PORT_ID)) && \
2107 (cfg.data.priority == get_flow_status(it->first.first, it->first.second, PRIORITY)) && \
2108 (cfg.data.cookie == get_flow_status(it->first.first, it->first.second, COOKIE)) && \
2109 (cfg.data.ingress_intf.intf_type == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_TYPE)) && \
2110 (cfg.data.ingress_intf.intf_id == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_ID)) && \
2111 (cfg.data.egress_intf.intf_type == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_TYPE)) && \
2112 (cfg.data.egress_intf.intf_id == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_ID)) && \
2113 (c_val.o_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_VID)) && \
2114 (c_val.o_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_PBITS)) && \
2115 (c_val.i_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_VID)) && \
2116 (c_val.i_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_PBITS)) && \
2117 (c_val.ether_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_ETHER_TYPE)) && \
2118 (c_val.ip_proto == get_flow_status(it->first.first, it->first.second, CLASSIFIER_IP_PROTO)) && \
2119 (c_val.src_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_SRC_PORT)) && \
2120 (c_val.dst_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_DST_PORT)) && \
2121 (c_val.pkt_tag_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_PKT_TAG_TYPE)) && \
2122 (cfg.data.egress_qos.type == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TYPE)) && \
2123 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_QUEUE_ID)) && \
2124 (cfg.data.egress_qos.tm_sched.id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TM_SCHED_ID)) && \
2125 (a_val.cmds_bitmask == get_flow_status(it->first.first, it->first.second, ACTION_CMDS_BITMASK)) && \
2126 (a_val.o_vid == get_flow_status(it->first.first, it->first.second, ACTION_O_VID)) && \
2127 (a_val.i_vid == get_flow_status(it->first.first, it->first.second, ACTION_I_VID)) && \
2128 (a_val.o_pbits == get_flow_status(it->first.first, it->first.second, ACTION_O_PBITS)) && \
2129 (a_val.i_pbits == get_flow_status(it->first.first, it->first.second, ACTION_I_PBITS)) && \
2130 (cfg.data.state == get_flow_status(it->first.first, it->first.second, STATE)) && \
2131 (cfg.data.group_id == get_flow_status(it->first.first, it->first.second, GROUP_ID));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002132#ifdef SHOW_FLOW_PARAM
2133 // Flow Parameter
2134 FLOW_PARAM_LOG();
2135#endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002136 if (b_duplicate_flow) {
2137 FLOW_LOG(WARNING, "Flow duplicate", 0);
2138 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
2139 }
2140 }
2141 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002142#endif // FLOW_CHECKER
2143#endif // SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002144
2145 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2146 if (err) {
2147 FLOW_LOG(ERROR, "Flow add failed", err);
2148 return bcm_to_grpc_err(err, "flow add failed");
2149 } else {
2150 FLOW_LOG(INFO, "Flow add ok", err);
2151 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002152 flow_map[std::pair<int, int>(key.flow_id,key.flow_type)] = flow_map.size();
2153 flow_id_counters = flow_map.size();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002154 bcmos_fastlock_unlock(&data_lock, 0);
Girish Gowdra252f4972020-09-07 21:24:01 -07002155
2156 }
Burak Gurdaga0523592021-02-24 15:17:47 +00002157
2158 /*
2159 Enable AES encryption on GEM ports if they are used in downstream unicast flows.
2160 Rationale: We can't do upstream encryption in GPON. This change addresses the common denominator (and also minimum viable)
2161 use case for both technologies which is downstream unicast GEM port encryption. Since the downstream traffic is inherently
2162 broadcast to all the ONUs behind a PON port, encrypting the individual subscriber traffic in this direction is important
2163 and considered good enough in terms of security (See Section 12.1 of G.984.3). For upstream unicast and downstream multicast
2164 GEM encryption, we need to make additional changes specific to XGSPON. This will be done as a future work.
2165 */
2166 if (aes_enabled && (access_intf_id >= 0) && (gemport_id >= GEM_PORT_ID_START) && (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM)) {
2167 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 +05302168 enable_encryption_for_gem_port(access_intf_id, gemport_id, board_technology);
Burak Gurdaga0523592021-02-24 15:17:47 +00002169 } else {
2170 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);
2171 }
2172
Girish Gowdra252f4972020-09-07 21:24:01 -07002173 return Status::OK;
2174}
2175
2176Status FlowRemoveWrapper_(const ::openolt::Flow* request) {
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002177 int32_t access_intf_id = request->access_intf_id();
2178 int32_t onu_id = request->onu_id();
2179 int32_t uni_id = request->uni_id();
2180 uint32_t tech_profile_id = request->tech_profile_id();
Girish Gowdra252f4972020-09-07 21:24:01 -07002181 uint64_t voltha_flow_id = request->flow_id();
2182 Status st;
2183
2184 // If Voltha flow is not installed, return fail
2185 if (! is_voltha_flow_installed(voltha_flow_id)) {
2186 OPENOLT_LOG(ERROR, openolt_log_id, "voltha_flow_id=%lu not found\n", voltha_flow_id);
2187 return ::Status(grpc::StatusCode::NOT_FOUND, "voltha-flow-not-found");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002188 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04002189
Girish Gowdra252f4972020-09-07 21:24:01 -07002190 const device_flow *dev_fl = get_device_flow(voltha_flow_id);
2191 if (dev_fl == NULL) {
2192 OPENOLT_LOG(ERROR, openolt_log_id, "device flow for voltha_flow_id=%lu in the cache is NULL\n", voltha_flow_id);
2193 return ::Status(grpc::StatusCode::INTERNAL, "device-flow-null-in-cache");
2194 }
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002195 std::string flow_type = dev_fl->flow_type;
Girish Gowdra252f4972020-09-07 21:24:01 -07002196 if (dev_fl->is_flow_replicated) {
2197 // Note: Here we are ignoring FlowRemove failures
2198 for (int i=0; i<NUMBER_OF_REPLICATED_FLOWS; i++) {
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002199 st = FlowRemove_(dev_fl->params[i].flow_id, flow_type);
Girish Gowdra252f4972020-09-07 21:24:01 -07002200 if (st.error_code() == grpc::StatusCode::OK) {
2201 free_flow_id(dev_fl->params[i].flow_id);
2202 }
2203 }
2204 } else {
2205 // Note: Here we are ignoring FlowRemove failures
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002206 st = FlowRemove_(dev_fl->params[0].flow_id, flow_type);
Girish Gowdra252f4972020-09-07 21:24:01 -07002207 if (st.error_code() == grpc::StatusCode::OK) {
2208 free_flow_id(dev_fl->params[0].flow_id);
2209 }
2210 }
2211 // remove the flow from cache on voltha flow removal
2212 remove_voltha_flow_from_cache(voltha_flow_id);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002213
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002214 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 -07002215 // Remove onu-uni mapping for the pon-gem key
2216 bcmos_fastlock_lock(&symmetric_datapath_flow_id_lock);
2217 symmetric_datapath_flow_id_map.erase(key);
2218 bcmos_fastlock_unlock(&symmetric_datapath_flow_id_lock, 0);
2219
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002220 return Status::OK;
2221}
2222
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002223Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
2224
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002225 bcmolt_flow_cfg cfg;
2226 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002227
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002228 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002229 key.flow_id = flow_id;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002230 if (flow_type == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002231 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002232 } else if (flow_type == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002233 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002234 } else if(flow_type == multicast) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002235 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002236 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002237 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002238 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
2239 }
2240
Jason Huang09b73ea2020-01-08 17:52:05 +08002241 OPENOLT_LOG(INFO, openolt_log_id, "flow remove received for flow_id=%u, flow_type=%s\n",
2242 flow_id, flow_type.c_str());
2243
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002244 bcmos_fastlock_lock(&acl_packet_trap_handler_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002245 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
2246 int32_t gemport_id = -1;
2247 int32_t intf_id = -1;
2248 int16_t acl_id = -1;
2249 if (flow_to_acl_map.count(fl_id_fl_dir) > 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002250
2251 acl_id_intf_id ac_id_if_id = flow_to_acl_map[fl_id_fl_dir];
2252 acl_id = std::get<0>(ac_id_if_id);
2253 intf_id = std::get<1>(ac_id_if_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002254 // cleanup acl only if it is a valid acl. If not valid acl, it may be datapath flow.
2255 if (acl_id >= 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002256 Status resp = handle_acl_rule_cleanup(acl_id, intf_id, flow_type);
Jason Huang09b73ea2020-01-08 17:52:05 +08002257 if (resp.ok()) {
2258 OPENOLT_LOG(INFO, openolt_log_id, "acl removed ok for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2259 flow_to_acl_map.erase(fl_id_fl_dir);
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002260
2261 // 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
2262 if (trap_to_host_pkt_info_with_vlan_for_flow_id.count(flow_id) > 0) {
2263 trap_to_host_pkt_info_with_vlan pkt_info_with_vlan = trap_to_host_pkt_info_with_vlan_for_flow_id[flow_id];
2264 // Formulate the trap_to_host_pkt_info tuple key
2265 trap_to_host_pkt_info pkt_info(std::get<0>(pkt_info_with_vlan),
2266 std::get<1>(pkt_info_with_vlan),
2267 std::get<2>(pkt_info_with_vlan),
2268 std::get<3>(pkt_info_with_vlan));
2269 // Extract the value corresponding to trap_to_host_pkt_info key from trap_to_host_vlan_ids_for_trap_to_host_pkt_info
2270 // The value is a list of vlan_ids for the given trap_to_host_pkt_info key
2271 // Remove the vlan_id from the list that corresponded to the flow being removed.
2272 if (trap_to_host_vlan_ids_for_trap_to_host_pkt_info.count(pkt_info) > 0) {
2273 trap_to_host_vlan_ids_for_trap_to_host_pkt_info[pkt_info].remove(std::get<4>(pkt_info_with_vlan));
2274 } else {
2275 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",
2276 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));
2277 }
2278
2279 } else {
2280 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);
2281 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002282 } else {
2283 OPENOLT_LOG(ERROR, openolt_log_id, "acl remove error for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2284 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002285 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002286 return resp;
2287 }
2288 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002289 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002290
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002291 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002292 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002293 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002294 flowid_to_gemport.erase(key.flow_id);
2295 port_to_flows[port_no].erase(key.flow_id);
2296 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
2297 }
2298 else
2299 {
2300 flowid_to_port.erase(key.flow_id);
2301 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002302 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002303
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002304 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002305
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002306 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002307 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07002308 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 -04002309 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
2310 }
2311
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002312 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002313 if (flow_id_counters != 0) {
2314 std::map<flow_pair, int>::iterator it;
2315 for(it = flow_map.begin(); it != flow_map.end(); it++) {
2316 if (it->first.first == flow_id && it->first.second == key.flow_type) {
2317 flow_id_counters -= 1;
2318 flow_map.erase(it);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002319 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002320 }
2321 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002322 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
2323
Jason Huang09b73ea2020-01-08 17:52:05 +08002324 flow_to_acl_map.erase(fl_id_fl_dir);
2325
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002326 bcmos_fastlock_unlock(&data_lock, 0);
2327
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002328 return Status::OK;
2329}
2330
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002331bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
2332 bcmos_errno err;
2333 bcmolt_tm_sched_cfg tm_sched_cfg;
2334 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2335 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
2336
Jason Huangbf45ffb2019-10-30 17:29:02 +08002337 //check TM scheduler has configured or not
2338 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2339 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002340 #ifdef TEST_MODE
2341 // It is impossible to mock the setting of tm_sched_cfg.data.state because
2342 // the actual bcmolt_cfg_get passes the address of tm_sched_cfg.hdr and we cannot
2343 // set the tm_sched_cfg.data.state. So a new stub function is created and address
2344 // of tm_sched_cfg is passed. This is one-of case where we need to add test specific
2345 // code in production code.
2346 err = bcmolt_cfg_get__tm_sched_stub(dev_id, &tm_sched_cfg);
2347 #else
Jason Huangbf45ffb2019-10-30 17:29:02 +08002348 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002349 #endif
Jason Huangbf45ffb2019-10-30 17:29:02 +08002350 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07002351 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 +08002352 return err;
2353 }
2354 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
2355 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
2356 return BCM_ERR_OK;
2357 }
2358
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002359 // bcmbal_tm_sched_owner
2360 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2361
2362 /**< The output of the tm_sched object instance */
2363 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
2364
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002365 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002366 // In upstream it is NNI scheduler
2367 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 -08002368 } else if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002369 // In downstream it is PON scheduler
2370 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2371 }
2372
2373 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2374
2375 // bcmbal_tm_sched_type
2376 // set the deafult policy to strict priority
2377 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2378
2379 // num_priorities: Max number of strict priority scheduling elements
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002380 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, NUM_OF_PRIORITIES);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002381
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002382 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2383 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002384 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
2385 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002386 return err;
2387 }
2388
2389 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2390 direction.c_str(), tm_sched_key.id, intf_id);
2391 return BCM_ERR_OK;
2392}
2393
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002394bcmos_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 -07002395 uint32_t alloc_id, ::tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
2396 ::tech_profile::SchedulingPolicy sched_policy, ::tech_profile::TrafficShapingInfo tf_sh_info,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002397 uint32_t tech_profile_id) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002398
2399 bcmos_errno err;
2400
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002401 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002402 bcmolt_tm_sched_cfg tm_sched_cfg;
2403 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002404 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 -04002405
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002406 // bcmbal_tm_sched_owner
2407 // In downstream it is sub_term scheduler
2408 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002409
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002410 /**< The output of the tm_sched object instance */
2411 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002412
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002413 // bcmbal_tm_sched_parent
2414 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2415 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 +00002416 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 +00002417 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 +00002418 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002419 be achieved using the' virtual' type of attachment.
2420 tm_sched_owner.u.sub_term.intf_id = intf_id;
2421 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2422 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002423
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002424 // bcmbal_tm_sched_type
2425 // set the deafult policy to strict priority
2426 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002427
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002428 // num_priorities: Max number of strict priority scheduling elements
2429 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002430
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002431 // bcmbal_tm_shaping
2432 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2433 uint32_t cir = tf_sh_info.cir();
2434 uint32_t pir = tf_sh_info.pir();
2435 uint32_t burst = tf_sh_info.pbs();
2436 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2437 cir, pir, burst);
2438 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2439 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2440 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2441 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2442 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2443 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002444 }
2445
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002446 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002447 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002448 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Girish Gowdra72cbee92021-11-05 15:16:18 -07002449intf_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, \
2450port_no, tm_sched_cfg.hdr.hdr.err_text, err);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002451 return err;
2452 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002453 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2454uni_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 -08002455
2456 } else { //upstream
Arthur Syu094df162022-04-21 17:50:06 +08002457 std::string intf_technology = intf_technologies[intf_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002458 bcmolt_itupon_alloc_cfg cfg;
2459 bcmolt_itupon_alloc_key key = { };
2460 key.pon_ni = intf_id;
2461 key.alloc_id = alloc_id;
Arthur Syu094df162022-04-21 17:50:06 +08002462 int bw_granularity = (intf_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
Burak Gurdag623fada2021-04-20 22:02:36 +00002463 /*
2464 PIR: Maximum Bandwidth
2465 CIR: Assured Bandwidth
2466 GIR: Fixed Bandwidth
2467 */
Burak Gurdag03919c72020-02-04 22:46:57 +00002468 int pir_bw = tf_sh_info.pir()*125; // conversion from kbps to bytes/sec
2469 int cir_bw = tf_sh_info.cir()*125; // conversion from kbps to bytes/sec
Burak Gurdag623fada2021-04-20 22:02:36 +00002470 int gir_bw = tf_sh_info.gir()*125; // conversion from kbps to bytes/sec
2471 int guaranteed_bw = cir_bw+gir_bw;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002472 //offset to match bandwidth granularity
2473 int offset_pir_bw = pir_bw%bw_granularity;
Burak Gurdag623fada2021-04-20 22:02:36 +00002474 int offset_gir_bw = gir_bw%bw_granularity;
2475 int offset_guaranteed_bw = guaranteed_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002476
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002477 pir_bw = pir_bw - offset_pir_bw;
Burak Gurdag623fada2021-04-20 22:02:36 +00002478 gir_bw = gir_bw - offset_gir_bw;
2479 guaranteed_bw = guaranteed_bw - offset_guaranteed_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002480
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002481 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002482
Burak Gurdag623fada2021-04-20 22:02:36 +00002483 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);
2484
2485 if (pir_bw == 0) {
2486 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be at least %d bytes/sec\n",
2487 (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2488 return BCM_ERR_PARM;
2489 } else if (pir_bw < guaranteed_bw) {
2490 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed bandwidth (%d)\n",
2491 pir_bw, guaranteed_bw);
2492 return BCM_ERR_PARM;
2493 }
2494
2495 // Setting additional bw eligibility and validating bw provisionings
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002496 switch (additional_bw) {
Burak Gurdag623fada2021-04-20 22:02:36 +00002497
2498 case tech_profile::AdditionalBW::AdditionalBW_BestEffort: //AdditionalBW_BestEffort - For T-Cont types 4 & 5
2499 if (pir_bw == guaranteed_bw) {
2500 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2501bandwidth for additional bandwidth eligibility of type Best Effort\n");
2502 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002503 }
2504 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2505 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002506
2507 case tech_profile::AdditionalBW::AdditionalBW_NA: //AdditionalBW_NA - For T-Cont types 3 & 5
2508 if (guaranteed_bw == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002509 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2510additional bandwidth eligibility of type Non-Assured (NA)\n");
2511 return BCM_ERR_PARM;
Burak Gurdag623fada2021-04-20 22:02:36 +00002512 } else if (pir_bw == guaranteed_bw) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002513 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
Burak Gurdag623fada2021-04-20 22:02:36 +00002514bandwidth for additional bandwidth eligibility of type Non-Assured\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002515 return BCM_ERR_PARM;
2516 }
2517 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2518 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002519
2520 case tech_profile::AdditionalBW::AdditionalBW_None: //AdditionalBW_None - For T-Cont types 1 & 2
2521 if (guaranteed_bw != pir_bw) {
2522 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be equal to maximum bandwidth \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002523for additional bandwidth eligibility of type None\n");
2524 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002525 }
2526 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2527 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002528
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002529 default:
Burak Gurdag623fada2021-04-20 22:02:36 +00002530 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid additional bandwidth eligibility value (%d) supplied.\n", additional_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002531 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002532 }
Burak Gurdag623fada2021-04-20 22:02:36 +00002533
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002534 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2535 in a fine granularity. */
2536 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
Burak Gurdag623fada2021-04-20 22:02:36 +00002537 /* Since we can assign minimum 64000 bytes/sec for cbr_rt_bw, we prefer assigning
2538 gir_bw to cbr_nrt_bw to allow smaller amounts.
2539 TODO: Specify CBR_RT_BW and CBR_NRT_BW separately from VOLTHA */
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002540 /* Fixed Bandwidth with no critical requirement of shaping */
Burak Gurdag623fada2021-04-20 22:02:36 +00002541 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, gir_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002542 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
Burak Gurdag623fada2021-04-20 22:02:36 +00002543 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, guaranteed_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002544 /* Maximum allocated bandwidth allowed for this alloc ID */
2545 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
Burak Gurdag623fada2021-04-20 22:02:36 +00002546
2547 if (pir_bw == gir_bw) { // T-Cont Type 1 --> set alloc type to NONE
2548 // the condition cir_bw == 0 is implicitly satistied
2549 OPENOLT_LOG(INFO, openolt_log_id, "Setting alloc type to NONE since maximum bandwidth is equal to fixed bandwidth\n");
2550 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NONE);
2551 } else { // For other T-Cont types, set alloc type to NSR. TODO: read the default from a config file.
2552 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
2553 }
2554
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002555 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002556 for skipped allocations during quiet window */
2557 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2558 /**< Allocation Profile index for CBR non-RT Bandwidth */
2559 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2560 /**< Allocation Profile index for CBR RT Bandwidth */
2561 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2562 /**< Alloc ID Weight used in case of Extended DBA mode */
2563 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2564 /**< Alloc ID Priority used in case of Extended DBA mode */
2565 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2566 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002567
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302568 bcmolt_onu_state onu_state;
2569 bool wait_for_alloc_cfg_cmplt = false;
2570 err = get_onu_state((bcmolt_interface)intf_id, (bcmolt_onu_id)onu_id, &onu_state);
2571 if (err) {
2572 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch onu status, intf_id = %d, onu_id = %d, err = %s\n",
2573 intf_id, onu_id, bcmos_strerror(err));
2574 return err;
2575 } else if (onu_state == BCMOLT_ONU_STATE_ACTIVE) {
2576 wait_for_alloc_cfg_cmplt = true;
2577 }
2578
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002579 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002580 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002581 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 -07002582port_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 -08002583 return err;
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302584 } else if (wait_for_alloc_cfg_cmplt) {
2585 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
2586 if (err) {
2587 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 +05302588port_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 +05302589 return err;
Girish Gowdra72cbee92021-11-05 15:16:18 -07002590 }
2591 } else {
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302592 OPENOLT_LOG(INFO, openolt_log_id, "onu not active, not waiting for alloc cfg complete, onu_state = %d, intf = %d, onu=%d\n",
2593 onu_state, intf_id, onu_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302594 }
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302595
Girish Gowdra96461052019-11-22 20:13:59 +05302596 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
2597port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
2598
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002599 }
2600
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002601 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002602}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002603
Girish Gowdra252f4972020-09-07 21:24:01 -07002604Status CreateTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002605 uint32_t intf_id = traffic_scheds->intf_id();
2606 uint32_t onu_id = traffic_scheds->onu_id();
2607 uint32_t uni_id = traffic_scheds->uni_id();
2608 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002609 std::string direction;
2610 unsigned int alloc_id;
Girish Gowdra252f4972020-09-07 21:24:01 -07002611 ::tech_profile::SchedulerConfig sched_config;
2612 ::tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002613 uint32_t priority;
2614 uint32_t weight;
Girish Gowdra252f4972020-09-07 21:24:01 -07002615 ::tech_profile::SchedulingPolicy sched_policy;
2616 ::tech_profile::TrafficShapingInfo traffic_shaping_info;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002617 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002618 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002619
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002620 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002621 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002622
2623 direction = GetDirection(traffic_sched.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002624 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002625 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002626 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002627
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002628 alloc_id = traffic_sched.alloc_id();
2629 sched_config = traffic_sched.scheduler();
2630 additional_bw = sched_config.additional_bw();
2631 priority = sched_config.priority();
2632 weight = sched_config.weight();
2633 sched_policy = sched_config.sched_policy();
2634 traffic_shaping_info = traffic_sched.traffic_shaping_info();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002635 tech_profile_id = traffic_sched.tech_profile_id();
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002636 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002637 sched_policy, traffic_shaping_info, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002638 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002639 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002640 return bcm_to_grpc_err(err, "Failed to create scheduler");
2641 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002642 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002643 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002644}
Jonathan Davis70c21812018-07-19 15:32:10 -04002645
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002646bcmos_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 -04002647
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002648 bcmos_errno err;
Girish Gowdra72cbee92021-11-05 15:16:18 -07002649 bcmolt_onu_state onu_state;
Girish Gowdra96461052019-11-22 20:13:59 +05302650 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002651
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002652 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002653 bcmolt_itupon_alloc_cfg cfg;
2654 bcmolt_itupon_alloc_key key = { };
2655 key.pon_ni = intf_id;
2656 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302657 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002658
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302659 bcmolt_onu_state onu_state;
2660 bool wait_for_alloc_cfg_cmplt = false;
2661 err = get_onu_state((bcmolt_interface)intf_id, (bcmolt_onu_id)onu_id, &onu_state);
2662 if (err) {
2663 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch onu status, intf_id = %d, onu_id = %d, err = %s\n",
2664 intf_id, onu_id, bcmos_strerror(err));
2665 return err;
2666 } else if (onu_state == BCMOLT_ONU_STATE_ACTIVE) {
2667 wait_for_alloc_cfg_cmplt = true;
2668 }
2669
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002670 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002671 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2672 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07002673 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s (%d)\n",
2674 direction.c_str(), intf_id, alloc_id, cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002675 return err;
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302676 } else if (wait_for_alloc_cfg_cmplt) {
2677 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2678 if (err) {
2679 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2680pon_intf %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,intf_id,alloc_id, bcmos_strerror(err));
2681 return err;
2682 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302683 } else {
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302684 OPENOLT_LOG(INFO, openolt_log_id, "onu not active, not waiting for alloc cfg complete, onu_state = %d, intf = %d, onu=%d\n",
2685 onu_state, intf_id, onu_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302686 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002687 } else if (direction == downstream) {
2688 bcmolt_tm_sched_cfg cfg;
2689 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002690
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002691 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2692 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302693 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002694 } else {
2695 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2696 return BCM_ERR_OK;
2697 }
Girish Gowdra96461052019-11-22 20:13:59 +05302698
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002699 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2700 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2701 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002702 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
Girish Gowdra72cbee92021-11-05 15:16:18 -07002703intf_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 +00002704 return err;
2705 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002706 }
2707
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002708 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d, tech_profile_id %d\n",
2709 direction.c_str(), sched_id, intf_id, onu_id, tech_profile_id);
2710 free_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002711 return BCM_ERR_OK;
2712}
2713
Girish Gowdra252f4972020-09-07 21:24:01 -07002714Status RemoveTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002715 uint32_t intf_id = traffic_scheds->intf_id();
2716 uint32_t onu_id = traffic_scheds->onu_id();
2717 uint32_t uni_id = traffic_scheds->uni_id();
2718 std::string direction;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002719 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002720 bcmos_errno err;
2721
2722 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002723 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002724
2725 direction = GetDirection(traffic_sched.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002726 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002727 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002728 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002729
2730 int alloc_id = traffic_sched.alloc_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002731 int tech_profile_id = traffic_sched.tech_profile_id();
2732 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002733 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002734 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002735 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2736 }
2737 }
2738 return Status::OK;
2739}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002740
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002741bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2742 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002743 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002744 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2745 bcmolt_tm_qmp_key tm_qmp_key;
2746 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002747
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002748 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2749 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002750 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed tm queue mapping profile count is 16.\n");
2751 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002752 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002753
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002754 tm_qmp_key.id = tm_qmp_id;
2755 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2756 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2757 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002758
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002759 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2760 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2761 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002762 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2763 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002764
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002765 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002766 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002767 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2768 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002769 return err;
2770 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002771
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002772 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2773 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002774 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002775}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002776
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002777bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2778 bcmos_errno err;
2779 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2780 bcmolt_tm_qmp_key tm_qmp_key;
2781 tm_qmp_key.id = tm_qmp_id;
2782
2783 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2784 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2785 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002786 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2787 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002788 return err;
2789 }
2790
2791 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2792 tm_qmp_key.id);
2793 return BCM_ERR_OK;
2794}
2795
2796bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2797 bcmos_errno err;
2798
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002799 /* Create default queues on the given PON/NNI scheduler */
2800 for (int queue_id = 0; queue_id < NUMBER_OF_DEFAULT_INTERFACE_QUEUES; queue_id++) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002801 bcmolt_tm_queue_cfg tm_queue_cfg;
2802 bcmolt_tm_queue_key tm_queue_key = {};
2803 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2804 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002805 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2806 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2807 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002808
2809 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2810 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2811 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2812
2813 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2814 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002815 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", \
2816 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 +00002817 return err;
2818 }
2819
2820 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2821 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2822 }
2823 return BCM_ERR_OK;
2824}
2825
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002826bcmos_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 +00002827 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 +00002828 bcmos_errno err;
2829 bcmolt_tm_queue_cfg cfg;
2830 bcmolt_tm_queue_key key = { };
2831 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 +00002832gemport_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 +00002833
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002834 key.sched_id = (direction == upstream) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002835 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002836
2837 if (priority > 7) {
2838 return BCM_ERR_RANGE;
2839 }
2840
2841 /* FIXME: The upstream queues have to be created once only.
2842 The upstream queues on the NNI scheduler are shared by all subscribers.
2843 When the first scheduler comes in, the queues get created, and are re-used by all others.
2844 Also, these queues should be present until the last subscriber exits the system.
2845 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2846
2847 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2848 for each GEM in TECH PROFILE */
2849 key.id = queue_id_list[priority];
2850
2851 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2852 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2853 key.id = 0;
2854 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2855 }
2856 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2857 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2858 }
2859 else {
2860 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2861 }
2862
2863 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2864
2865 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2866 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
Girish Gowdra5287fde2021-07-31 00:41:45 +00002867 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002868
2869 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2870 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002871 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
Girish Gowdra72cbee92021-11-05 15:16:18 -07002872sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, tech_profile_id %d, err = %s (%d)\n", \
2873 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 +00002874 return err;
2875 }
2876
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302877 if (direction == upstream || direction == downstream) {
Thiyagarajan Subramani19168f52021-05-25 23:26:41 +05302878 Status st = install_gem_port(access_intf_id, onu_id, uni_id, gemport_id, board_technology);
Girish Gowdra252f4972020-09-07 21:24:01 -07002879 if (st.error_code() != grpc::StatusCode::ALREADY_EXISTS && st.error_code() != grpc::StatusCode::OK) {
2880 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);
2881 return BCM_ERR_INTERNAL;
2882 }
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002883 if (direction == upstream) {
2884 // Create the pon-gem to onu-uni mapping
2885 pon_gem pg(access_intf_id, gemport_id);
2886 onu_uni ou(onu_id, uni_id);
2887 bcmos_fastlock_lock(&pon_gem_to_onu_uni_map_lock);
2888 pon_gem_to_onu_uni_map[pg] = ou;
2889 bcmos_fastlock_unlock(&pon_gem_to_onu_uni_map_lock, 0);
2890 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002891 }
2892
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002893 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 +00002894intf_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 +00002895 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002896}
2897
Girish Gowdra252f4972020-09-07 21:24:01 -07002898Status CreateTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002899 uint32_t intf_id = traffic_queues->intf_id();
2900 uint32_t onu_id = traffic_queues->onu_id();
2901 uint32_t uni_id = traffic_queues->uni_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002902 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002903 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002904 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002905 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002906 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 +00002907
2908 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2909 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2910 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2911 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002912 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002913
2914 direction = GetDirection(traffic_queue.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002915 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002916 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002917 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002918
2919 queues_priority_q[i] = traffic_queue.priority();
2920 queues_pbit_map[i] = traffic_queue.pbit_map();
2921 }
2922
2923 std::vector<uint32_t> tmq_map_profile(8, 0);
2924 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2925 queues_priority_q, COUNT_OF(queues_priority_q));
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002926 sched_id = (direction == upstream) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002927 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002928
2929 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2930 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002931 err = CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2932 if (err != BCM_ERR_OK) {
2933 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2934 return bcm_to_grpc_err(err, "Failed to create tm queue mapping profile");
2935 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002936 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2937 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2938 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2939 }
2940 }
2941
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002942 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002943 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002944
2945 direction = GetDirection(traffic_queue.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002946 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002947 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002948 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002949
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002950 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 +00002951
Girish Gowdruf26cf882019-05-01 23:47:58 -07002952 // If the queue exists already, lets not return failure and break the loop.
2953 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002954 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002955 return bcm_to_grpc_err(err, "Failed to create queue");
2956 }
2957 }
2958 return Status::OK;
2959}
2960
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002961bcmos_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 +00002962 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 +00002963 bcmolt_tm_queue_cfg cfg;
2964 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002965 bcmos_errno err;
2966
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302967 // Gemports are bi-directional (except in multicast case). We create the gem port when we create the
2968 // upstream/downstream queue (see CreateQueue function) and it makes sense to delete them when remove the queues.
2969 // For multicast case we do not manage the install/remove of gem port in agent application. It is managed by BAL.
2970 if (direction == upstream || direction == downstream) {
Thiyagarajan Subramani19168f52021-05-25 23:26:41 +05302971 Status st = remove_gem_port(access_intf_id, onu_id, uni_id, gemport_id, board_technology);
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302972 if (st.error_code() != grpc::StatusCode::OK) {
2973 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 -07002974 // We should further cleanup proceed, do not return error yet..
2975 // return BCM_ERR_INTERNAL;
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302976 }
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002977 if (direction == upstream) {
2978 // Remove the pon-gem to onu-uni mapping
2979 pon_gem pg(access_intf_id, gemport_id);
2980 bcmos_fastlock_lock(&pon_gem_to_onu_uni_map_lock);
2981 pon_gem_to_onu_uni_map.erase(pg);
2982 bcmos_fastlock_unlock(&pon_gem_to_onu_uni_map_lock, 0);
2983 }
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302984 }
2985
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002986 if (direction == downstream) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002987 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2988 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 +00002989 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002990 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002991 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 -08002992 return BCM_ERR_OK;
2993 }
2994 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002995 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2996 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002997 return BCM_ERR_OK;
2998 }
2999
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003000 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
3001 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
3002 // Reset the queue id to 0 when using fixed queue.
3003 key.id = 0;
3004 }
3005 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
3006 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
3007 }
3008 else {
3009 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
3010 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003011
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003012 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
3013 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003014 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003015 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 -07003016tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s (%d)\n",
3017 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 -08003018 return err;
3019 }
3020
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003021 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
3022intf_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 -08003023
3024 return BCM_ERR_OK;
3025}
3026
Girish Gowdra252f4972020-09-07 21:24:01 -07003027Status RemoveTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003028 uint32_t intf_id = traffic_queues->intf_id();
3029 uint32_t onu_id = traffic_queues->onu_id();
3030 uint32_t uni_id = traffic_queues->uni_id();
3031 uint32_t port_no = traffic_queues->port_no();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00003032 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003033 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003034 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003035 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003036 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 -07003037 Status ret_code = Status::OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003038
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003039 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07003040 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003041
3042 direction = GetDirection(traffic_queue.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08003043 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003044 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08003045 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003046
Burak Gurdag2f2618c2020-04-23 13:20:30 +00003047 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 -08003048 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003049 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdra72cbee92021-11-05 15:16:18 -07003050 ret_code = bcm_to_grpc_err(err, "Failed to remove one or more queues");
3051 // Do not return here. We should continue to remove the remaining queues and its associated gem ports
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003052 }
Jonathan Davis70c21812018-07-19 15:32:10 -04003053 }
3054
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08003055 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE && (direction == upstream || \
3056 direction == downstream && is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id))) {
3057 sched_id = (direction == upstream) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00003058 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003059
3060 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
3061 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05003062 err = RemoveTrafficQueueMappingProfile(tm_qmp_id);
3063 if (err != BCM_ERR_OK) {
3064 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, err = %s\n", bcmos_strerror(err));
3065 return bcm_to_grpc_err(err, "Failed to remove tm queue mapping profile");
3066 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003067 }
3068 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003069 clear_qos_type(intf_id, onu_id, uni_id);
Girish Gowdra72cbee92021-11-05 15:16:18 -07003070 return ret_code;
Jonathan Davis70c21812018-07-19 15:32:10 -04003071}
Jason Huangbf45ffb2019-10-30 17:29:02 +08003072
Girish Gowdra252f4972020-09-07 21:24:01 -07003073Status PerformGroupOperation_(const ::openolt::Group *group_cfg) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003074
3075 bcmos_errno err;
3076 bcmolt_group_key key = {};
3077 bcmolt_group_cfg grp_cfg_obj;
3078 bcmolt_group_members_update grp_mem_upd;
3079 bcmolt_members_update_command grp_mem_upd_cmd;
3080 bcmolt_group_member_info member_info = {};
3081 bcmolt_group_member_info_list_u8 members = {};
3082 bcmolt_intf_ref interface_ref = {};
3083 bcmolt_egress_qos egress_qos = {};
3084 bcmolt_tm_sched_ref tm_sched_ref = {};
3085 bcmolt_action a_val = {};
3086
3087 uint32_t group_id = group_cfg->group_id();
3088
3089 OPENOLT_LOG(INFO, openolt_log_id, "PerformGroupOperation request received for Group %d\n", group_id);
3090
3091 if (group_id >= 0) {
3092 key.id = group_id;
3093 }
3094 else {
3095 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
3096 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
3097 }
3098
3099 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3100 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
3101
3102 OPENOLT_LOG(INFO, openolt_log_id, "Checking if Group %d exists...\n",group_id);
3103
3104 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
3105 if (err != BCM_ERR_OK) {
3106 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
3107 return bcm_to_grpc_err(err, "Error in querying group");
3108 }
3109
3110 members.len = group_cfg->members_size();
3111
3112 // IMPORTANT: A member cannot be added to a group if the group type is not determined.
3113 // Group type is determined after a flow is assigned to it.
3114 // Therefore, a group must be created first, then a flow (with multicast type) must be assigned to it.
3115 // Only then we can add members to the group.
3116
3117 // if group does not exist, create it and return.
3118 if (grp_cfg_obj.data.state == BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
3119
3120 if (members.len != 0) {
3121 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);
3122 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Non-empty member list given for non-existent group");
3123 } else {
3124
3125 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3126 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, cookie, key.id);
3127
3128 /* Setting group actions and action parameters, if any.
3129 Only remove_outer_tag and translate_inner_tag actions and i_vid action parameter
3130 are supported for multicast groups in BAL 3.1.
3131 */
3132 const ::openolt::Action& action = group_cfg->action();
3133 const ::openolt::ActionCmd &cmd = action.cmd();
3134
3135 bcmolt_action_cmd_id cmd_bmask = BCMOLT_ACTION_CMD_ID_NONE;
3136 if (cmd.remove_outer_tag()) {
3137 OPENOLT_LOG(INFO, openolt_log_id, "Action remove_outer_tag applied to Group %d.\n", group_id);
3138 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
3139 }
3140
3141 if (cmd.translate_inner_tag()) {
3142 OPENOLT_LOG(INFO, openolt_log_id, "Action translate_inner_tag applied to Group %d.\n", group_id);
3143 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG);
3144 }
3145
3146 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, cmd_bmask);
3147
3148 if (action.i_vid()) {
3149 OPENOLT_LOG(INFO, openolt_log_id, "Setting action parameter i_vid=%d for Group %d.\n", action.i_vid(), group_id);
3150 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
3151 }
3152
3153 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, action, a_val);
3154
3155 // Create group
3156 err = bcmolt_cfg_set(dev_id, &(grp_cfg_obj.hdr));
3157
3158 if (BCM_ERR_OK != err) {
3159 BCM_LOG(ERROR, openolt_log_id, "Failed to create Group %d, err = %s (%d)\n", key.id, bcmos_strerror(err), err);
3160 return bcm_to_grpc_err(err, "Error in creating group");
3161 }
3162
3163 BCM_LOG(INFO, openolt_log_id, "Group %d has been created and configured with empty member list.\n", key.id);
3164 return Status::OK;
3165 }
3166 }
3167
3168 // The group already exists. Continue configuring it according to the update member command.
3169
3170 OPENOLT_LOG(INFO, openolt_log_id, "Configuring existing Group %d.\n",group_id);
3171
3172 // MEMBER LIST CONSTRUCTION
3173 // Note that members.len can be 0 here. if the group already exists and the command is SET then sending
3174 // empty list to the group is a legit operation and this actually empties the member list.
3175 members.arr = (bcmolt_group_member_info*)bcmos_calloc((members.len)*sizeof(bcmolt_group_member_info));
3176
3177 if (!members.arr) {
3178 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to allocate memory for group member list.\n");
3179 return grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "Memory exhausted during member list creation");
3180 }
3181
3182 /* SET GROUP MEMBERS UPDATE COMMAND */
Girish Gowdra252f4972020-09-07 21:24:01 -07003183 ::openolt::Group::GroupMembersCommand command = group_cfg->command();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003184 switch(command) {
Girish Gowdra252f4972020-09-07 21:24:01 -07003185 case ::openolt::Group::SET_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003186 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_SET;
3187 OPENOLT_LOG(INFO, openolt_log_id, "Setting %d members for Group %d.\n", members.len, group_id);
3188 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003189 case ::openolt::Group::ADD_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003190 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_ADD;
3191 OPENOLT_LOG(INFO, openolt_log_id, "Adding %d members to Group %d.\n", members.len, group_id);
3192 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003193 case ::openolt::Group::REMOVE_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003194 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_REMOVE;
3195 OPENOLT_LOG(INFO, openolt_log_id, "Removing %d members from Group %d.\n", members.len, group_id);
3196 break;
3197 default :
3198 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid value %d for group member command.\n", command);
3199 bcmos_free(members.arr);
3200 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group member command");
3201 }
3202
3203 // SET MEMBERS LIST
3204 for (int i = 0; i < members.len; i++) {
3205
Girish Gowdra252f4972020-09-07 21:24:01 -07003206 if (command == ::openolt::Group::REMOVE_MEMBERS) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003207 OPENOLT_LOG(INFO, openolt_log_id, "Removing group member %d from group %d\n",i,key.id);
3208 } else {
3209 OPENOLT_LOG(INFO, openolt_log_id, "Adding group member %d to group %d\n",i,key.id);
3210 }
3211
Girish Gowdra252f4972020-09-07 21:24:01 -07003212 ::openolt::GroupMember *member = (::openolt::GroupMember *) &group_cfg->members()[i];
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003213
3214 // Set member interface type
Girish Gowdra252f4972020-09-07 21:24:01 -07003215 ::openolt::GroupMember::InterfaceType if_type = member->interface_type();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003216 switch(if_type){
Girish Gowdra252f4972020-09-07 21:24:01 -07003217 case ::openolt::GroupMember::PON :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003218 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_PON);
3219 OPENOLT_LOG(INFO, openolt_log_id, "Interface type PON is assigned to GroupMember %d\n",i);
3220 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003221 case ::openolt::GroupMember::EPON_1G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003222 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_1_G);
3223 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_1G is assigned to GroupMember %d\n",i);
3224 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003225 case ::openolt::GroupMember::EPON_10G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003226 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_10_G);
3227 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_10G is assigned to GroupMember %d\n",i);
3228 break;
3229 default :
3230 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid interface type value %d for GroupMember %d.\n",if_type,i);
3231 bcmos_free(members.arr);
3232 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface type for a group member");
3233 }
3234
3235 // Set member interface id
3236 if (member->interface_id() >= 0) {
3237 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_id, member->interface_id());
3238 OPENOLT_LOG(INFO, openolt_log_id, "Interface %d is assigned to GroupMember %d\n", member->interface_id(), i);
3239 } else {
3240 bcmos_free(members.arr);
3241 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface id for a group member");
3242 }
3243
3244 // Set member interface_ref
3245 BCMOLT_FIELD_SET(&member_info, group_member_info, intf, interface_ref);
3246
3247 // Set member gem_port_id. This must be a multicast gemport.
3248 if (member->gem_port_id() >= 0) {
3249 BCMOLT_FIELD_SET(&member_info, group_member_info, svc_port_id, member->gem_port_id());
3250 OPENOLT_LOG(INFO, openolt_log_id, "GEM Port %d is assigned to GroupMember %d\n", member->gem_port_id(), i);
3251 } else {
3252 bcmos_free(members.arr);
3253 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid gem port id for a group member");
3254 }
3255
3256 // Set member scheduler id and queue_id
3257 uint32_t tm_sched_id = get_default_tm_sched_id(member->interface_id(), downstream);
3258 OPENOLT_LOG(INFO, openolt_log_id, "Scheduler %d is assigned to GroupMember %d\n", tm_sched_id, i);
3259 BCMOLT_FIELD_SET(&tm_sched_ref, tm_sched_ref, id, tm_sched_id);
3260 BCMOLT_FIELD_SET(&egress_qos, egress_qos, tm_sched, tm_sched_ref);
3261
3262 // We assume that all multicast traffic destined to a PON port is using the same fixed queue.
3263 uint32_t tm_queue_id;
3264 if (member->priority() >= 0 && member->priority() < NUMBER_OF_DEFAULT_INTERFACE_QUEUES) {
3265 tm_queue_id = queue_id_list[member->priority()];
3266 OPENOLT_LOG(INFO, openolt_log_id, "Queue %d is assigned to GroupMember %d\n", tm_queue_id, i);
3267 BCMOLT_FIELD_SET(&egress_qos, egress_qos, type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
3268 BCMOLT_FIELD_SET(&egress_qos.u.fixed_queue, egress_qos_fixed_queue, queue_id, tm_queue_id);
3269 } else {
3270 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid fixed queue priority/ID %d for GroupMember %d\n", member->priority(), i);
3271 bcmos_free(members.arr);
3272 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid queue priority for a group member");
3273 }
3274
3275 BCMOLT_FIELD_SET(&member_info, group_member_info, egress_qos, egress_qos);
3276 BCMOLT_ARRAY_ELEM_SET(&(members), i, member_info);
3277 }
3278
3279 BCMOLT_OPER_INIT(&grp_mem_upd, group, members_update, key);
3280 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.members, members);
3281 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.command, grp_mem_upd_cmd);
3282
3283 err = bcmolt_oper_submit(dev_id, &(grp_mem_upd.hdr));
3284 bcmos_free(members.arr);
3285
3286 if (BCM_ERR_OK != err) {
3287 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);
3288 return bcm_to_grpc_err(err, "Failed to submit members update operation for the group");
3289 }
3290
3291 OPENOLT_LOG(INFO, openolt_log_id, "Successfully submitted members update operation for Group %d\n", key.id);
3292
3293 return Status::OK;
3294}
Burak Gurdageb4ca2e2020-06-15 07:48:26 +00003295
3296Status DeleteGroup_(uint32_t group_id) {
3297
3298 bcmos_errno err = BCM_ERR_OK;
3299 bcmolt_group_cfg grp_cfg_obj;
3300 bcmolt_group_key key = {};
3301
3302
3303 OPENOLT_LOG(INFO, openolt_log_id, "Delete request received for group %d\n", group_id);
3304
3305 if (group_id >= 0) {
3306 key.id = group_id;
3307 } else {
3308 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
3309 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
3310 }
3311
3312 /* init the BAL INIT API */
3313 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3314
3315 OPENOLT_LOG(DEBUG, openolt_log_id, "Checking if group %d exists...\n",group_id);
3316
3317 // CONFIGURE GROUP MEMBERS
3318 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
3319 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
3320
3321 if (err != BCM_ERR_OK) {
3322 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
3323 return bcm_to_grpc_err(err, "Error in querying group");
3324 }
3325
3326 if (grp_cfg_obj.data.state != BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
3327 OPENOLT_LOG(DEBUG, openolt_log_id, "Group %d exists. Will be deleted.\n",group_id);
3328 err = bcmolt_cfg_clear(dev_id, &(grp_cfg_obj.hdr));
3329 if (err != BCM_ERR_OK) {
3330 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d cannot be deleted err = %s (%d).\n", group_id, bcmos_strerror(err), err);
3331 return bcm_to_grpc_err(err, "Failed to delete group");;
3332 }
3333 } else {
3334 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d does not exist.\n", group_id);
3335 return Status(grpc::StatusCode::NOT_FOUND, "Group not found");
3336 }
3337
3338 OPENOLT_LOG(INFO, openolt_log_id, "Group %d has been deleted successfully.\n", group_id);
3339 return Status::OK;
Jason Huang1d9cfce2020-05-20 22:58:47 +08003340}
3341
Girish Gowdra252f4972020-09-07 21:24:01 -07003342Status GetLogicalOnuDistanceZero_(uint32_t intf_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003343 bcmos_errno err = BCM_ERR_OK;
3344 uint32_t mld = 0;
3345 double LD0;
3346
3347 err = getOnuMaxLogicalDistance(intf_id, &mld);
3348 if (err != BCM_ERR_OK) {
3349 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3350 }
3351
3352 LD0 = LOGICAL_DISTANCE(mld*1000, MINIMUM_ONU_RESPONSE_RANGING_TIME, ONU_BIT_TRANSMISSION_DELAY);
3353 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance zero is %f, (PON %d)\n", LD0, intf_id);
3354 response->set_intf_id(intf_id);
3355 response->set_logical_onu_distance_zero(LD0);
3356
3357 return Status::OK;
3358}
3359
Girish Gowdra252f4972020-09-07 21:24:01 -07003360Status GetLogicalOnuDistance_(uint32_t intf_id, uint32_t onu_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003361 bcmos_errno err = BCM_ERR_OK;
3362 bcmolt_itu_onu_params itu = {};
3363 bcmolt_onu_cfg onu_cfg;
3364 bcmolt_onu_key onu_key = {};
3365 uint32_t mld = 0;
3366 double LDi;
3367
3368 onu_key.pon_ni = intf_id;
3369 onu_key.onu_id = onu_id;
3370
3371 err = getOnuMaxLogicalDistance(intf_id, &mld);
3372 if (err != BCM_ERR_OK) {
3373 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3374 }
3375
3376 /* Initialize the API struct. */
3377 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
3378 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
3379 BCMOLT_FIELD_SET_PRESENT(&itu, itu_onu_params, ranging_time);
3380 BCMOLT_FIELD_SET(&onu_cfg.data, onu_cfg_data, itu, itu);
3381 #ifdef TEST_MODE
3382 // It is impossible to mock the setting of onu_cfg.data.onu_state because
3383 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
3384 // set the onu_cfg.data.onu_state. So a new stub function is created and address
3385 // of onu_cfg is passed. This is one-of case where we need to add test specific
3386 // code in production code.
3387 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
3388 #else
3389 /* Call API function. */
3390 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
3391 #endif
3392 if (err != BCM_ERR_OK) {
3393 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);
3394 return bcm_to_grpc_err(err, "Failed to retrieve ONU ranging time");
3395 }
3396
3397 if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_ACTIVE) {
3398 OPENOLT_LOG(ERROR, openolt_log_id, "ONU is not yet activated (PON %d, ONU id %d)\n", intf_id, onu_id);
3399 return bcm_to_grpc_err(BCM_ERR_PARM, "ONU is not yet activated\n");
3400 }
3401
3402 LDi = LOGICAL_DISTANCE(mld*1000, onu_cfg.data.itu.ranging_time, ONU_BIT_TRANSMISSION_DELAY);
3403 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance is %f, (PON %d, ONU id %d)\n", LDi, intf_id, onu_id);
3404 response->set_intf_id(intf_id);
3405 response->set_onu_id(onu_id);
3406 response->set_logical_onu_distance(LDi);
3407
3408 return Status::OK;
3409}
Burak Gurdag74e3ab82020-12-17 13:35:06 +00003410
3411Status GetOnuStatistics_(uint32_t intf_id, uint32_t onu_id, openolt::OnuStatistics* onu_stats) {
3412 bcmos_errno err;
3413
3414 err = get_onu_statistics((bcmolt_interface_id)intf_id, (bcmolt_onu_id)onu_id, onu_stats);
3415
3416 if (err != BCM_ERR_OK) {
3417 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));
3418 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of ONU statistics failed");
3419 }
3420
3421 OPENOLT_LOG(INFO, openolt_log_id, "retrieved ONU statistics for PON ID = %d, ONU ID = %d\n", (int)intf_id, (int)onu_id);
3422 return Status::OK;
3423}
3424
3425Status GetGemPortStatistics_(uint32_t intf_id, uint32_t gemport_id, openolt::GemPortStatistics* gemport_stats) {
3426 bcmos_errno err;
3427
3428 err = get_gemport_statistics((bcmolt_interface_id)intf_id, (bcmolt_gem_port_id)gemport_id, gemport_stats);
3429
3430 if (err != BCM_ERR_OK) {
3431 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));
3432 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of GEMPORT statistics failed");
3433 }
3434
3435 OPENOLT_LOG(INFO, openolt_log_id, "retrieved GEMPORT statistics for PON ID = %d, GEMPORT ID = %d\n", (int)intf_id, (int)gemport_id);
3436 return Status::OK;
3437}
Orhan Kupusogluec57af02021-05-12 12:38:17 +00003438
3439Status GetPonRxPower_(uint32_t intf_id, uint32_t onu_id, openolt::PonRxPowerData* response) {
3440 bcmos_errno err = BCM_ERR_OK;
3441
3442 // check the PON intf id
3443 if (intf_id >= MAX_SUPPORTED_PON) {
3444 err = BCM_ERR_PARM;
3445 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pon intf_id - intf_id: %d, onu_id: %d\n",
3446 intf_id, onu_id);
3447 return bcm_to_grpc_err(err, "invalid pon intf_id");
3448 }
3449
3450 bcmolt_onu_rssi_measurement onu_oper; /* declare main API struct */
3451 bcmolt_onu_key onu_key; /**< Object key. */
3452 onu_rssi_compltd_key key(intf_id, onu_id);
3453 Queue<onu_rssi_complete_result> queue;
3454
3455 OPENOLT_LOG(INFO, openolt_log_id, "GetPonRxPower - intf_id %d, onu_id %d\n", intf_id, onu_id);
3456
3457 onu_key.onu_id = onu_id;
3458 onu_key.pon_ni = intf_id;
3459 /* Initialize the API struct. */
3460 BCMOLT_OPER_INIT(&onu_oper, onu, rssi_measurement, onu_key);
3461 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
3462 if (err == BCM_ERR_OK) {
3463 // initialize map
3464 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3465 onu_rssi_compltd_map.insert({key, &queue});
3466 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3467 } else {
3468 OPENOLT_LOG(ERROR, openolt_log_id, "failed to measure rssi rx power - intf_id: %d, onu_id: %d, err = %s (%d): %s\n",
3469 intf_id, onu_id, bcmos_strerror(err), err, onu_oper.hdr.hdr.err_text);
3470 return bcm_to_grpc_err(err, "failed to measure rssi rx power");
3471 }
3472
3473 onu_rssi_complete_result completed{};
3474 if (!queue.pop(completed, ONU_RSSI_COMPLETE_WAIT_TIMEOUT)) {
3475 // invalidate the queue pointer
3476 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3477 onu_rssi_compltd_map[key] = NULL;
3478 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3479 err = BCM_ERR_TIMEOUT;
3480 OPENOLT_LOG(ERROR, openolt_log_id, "timeout waiting for RSSI Measurement Completed indication intf_id %d, onu_id %d\n",
3481 intf_id, onu_id);
3482 } else {
3483 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",
3484 completed.pon_intf_id, completed.onu_id, completed.status.c_str(), completed.reason, completed.rx_power_mean_dbm);
3485
3486 response->set_intf_id(completed.pon_intf_id);
3487 response->set_onu_id(completed.onu_id);
3488 response->set_status(completed.status);
3489 response->set_fail_reason(static_cast<::openolt::PonRxPowerData_RssiMeasurementFailReason>(completed.reason));
3490 response->set_rx_power_mean_dbm(completed.rx_power_mean_dbm);
3491 }
3492
3493 // Remove entry from map
3494 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3495 onu_rssi_compltd_map.erase(key);
3496 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3497
3498 if (err == BCM_ERR_OK) {
3499 return Status::OK;
3500 } else {
3501 return bcm_to_grpc_err(err, "timeout waiting for pon rssi measurement complete indication");
3502 }
3503}