blob: 8f6ea7b3e90fb335e4c15498b156d28e61d27d9a [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
Girish Gowdrab0337eb2022-03-25 16:44:21 -0700406 /* 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.*/
Thiyagarajan Subramani4e62e172021-06-25 17:31:30 +0530409 if (dev == 1 && (MODEL_ID == "rlt-1600g-w" || MODEL_ID == "rlt-1600x-w")) {
Girish Gowdrab0337eb2022-03-25 16:44:21 -0700410 continue;
411 }
Thiyagarajan Subramani4e62e172021-06-25 17:31:30 +0530412
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
Girish Gowdrab0337eb2022-03-25 16:44:21 -0700419 /* 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. */
Thiyagarajan Subramani3e8bfd92021-04-26 15:07:14 +0530422 reset_pon_device(dev);
Girish Gowdrab0337eb2022-03-25 16:44:21 -0700423 bcmolt_system_mode sm;
424 #ifdef DYNAMIC_PON_TRX_SUPPORT
425 auto sm_res = ponTrx.get_mac_system_mode(dev, ponTrx.get_sfp_presence_data());
426 if (!sm_res.second) {
427 OPENOLT_LOG(ERROR, openolt_log_id, "could not read mac system mode. dev_id = %d\n", dev);
428 continue;
429 }
430 sm = sm_res.first;
431 #else
432 sm = DEFAULT_MAC_SYSTEM_MODE;
433 #endif
434 BCMOLT_MSG_FIELD_SET (&oper, system_mode, sm);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000435 if (MODEL_ID == "asfvolt16") {
436 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000437 } else if (MODEL_ID == "asgvolt64") {
438 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
439 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
Thiyagarajan Subramani4e62e172021-06-25 17:31:30 +0530440 } else if (MODEL_ID == "rlt-3200g-w" || MODEL_ID == "rlt-1600g-w") {
Thiyagarajan Subramani3e8bfd92021-04-26 15:07:14 +0530441 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_NONE);
442 if(dev == 1) {
443 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
444 }
445 BCMOLT_MSG_FIELD_SET (&oper, ras_ddr_mode, BCMOLT_RAS_DDR_USAGE_MODE_TWO_DDRS);
446 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
Thiyagarajan Subramani4e62e172021-06-25 17:31:30 +0530447 } else if (MODEL_ID == "rlt-1600x-w") {
448 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_NONE);
449 BCMOLT_MSG_FIELD_SET (&oper, ras_ddr_mode, BCMOLT_RAS_DDR_USAGE_MODE_TWO_DDRS);
450 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
Arthur Syu094df162022-04-21 17:50:06 +0800451 } else if (MODEL_ID == "sda3016ss") {
452 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_12_P_5_G);
453 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_TWO_TO_ONE);
454 BCMOLT_MSG_FIELD_SET (&oper, ras_ddr_mode, BCMOLT_RAS_DDR_USAGE_MODE_TWO_DDRS);
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
Girish Gowdrab0337eb2022-03-25 16:44:21 -0700945 // TODO: Currently the PON Type is set automatically when the MAC System Mode is set. But it could be explicitely set here again.
946 // The data for the PON type is availabe in the PonTrx object (check trx_data)
947
kesavandc1f2db92020-08-31 15:32:06 +0530948 //Enable AES Encryption
949 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.key_exchange, BCMOLT_CONTROL_STATE_ENABLE);
950 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.authentication, BCMOLT_CONTROL_STATE_ENABLE);
951 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.fail_due_to_authentication_failure, BCMOLT_CONTROL_STATE_ENABLE);
952
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000953 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
954 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
955
956 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
957 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500958 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 +0000959 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
960 }
961 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
962 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500963 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 +0000964 return bcm_to_grpc_err(err, "Failed to enable PON interface");
965 }
966 else {
967 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
968 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
969 CreateDefaultSched(intf_id, downstream);
970 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400971 }
972
973 return Status::OK;
974}
975
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500976Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000977 bcmos_errno err;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400978 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000979 bcmolt_device_key dev_key = { };
980 bcmolt_olt_cfg olt_cfg = { };
981 bcmolt_olt_key olt_key = { };
982 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
983 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500984
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000985 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
986 topo.topology_maps.arr = &topo_map[0];
987 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
988 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
989 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400990 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000991 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400992 #ifdef TEST_MODE
993 // It is impossible to mock the setting of olt_cfg.data.bal_state because
994 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
995 // set the olt_cfg.data.topology. So a new stub function is created and address
996 // of olt_cfg is passed. This is one-of case where we need to test add specific
997 // code in production code.
998 err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
999 #else
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001000 err = bcmolt_cfg_get_mult_retry(dev_id, &olt_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001001 #endif
1002 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001003 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 +00001004 return bcm_to_grpc_err(err, "cfg: Failed to query OLT topology");
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001005 }
1006
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001007 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
1008 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001009
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001010 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
1011 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001012 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001013
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001014 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
1015 num_of_nni_ports,
1016 num_of_pon_ports,
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001017 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001018
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001019 uint32_t num_failed_cfg_gets = 0;
Jason Huang09b73ea2020-01-08 17:52:05 +08001020 static std::string openolt_version = firmware_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001021 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
1022 dev_key.device_id = devid;
1023 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
1024 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
1025 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
1026 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001027 err = bcmolt_cfg_get_mult_retry(dev_id, &dev_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001028 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001029 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 +00001030 num_failed_cfg_gets++;
1031 continue;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001032 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001033
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001034 std::string bal_version;
1035 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
1036 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
1037 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
Jason Huang09b73ea2020-01-08 17:52:05 +08001038 firmware_version = "BAL." + bal_version + "__" + openolt_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001039
1040 switch(dev_cfg.data.system_mode) {
1041 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
1042 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
1043 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
1044 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
1045 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
1046 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
1047 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
1048 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
1049 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
1050 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 +08001051 case 38:
1052 board_technology = "XGS-PON";
1053 FILL_ARRAY2(intf_technologies,devid*16,(devid+1)*16,"XGS-PON");
1054 FILL_ARRAY2(intf_technologies,devid*16+1,(devid+1)*16+1,"GPON");
1055 break;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001056 }
1057
1058 switch(dev_cfg.data.chip_family) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001059 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X: chip_family = "Maple"; break;
1060 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X: chip_family = "Aspen"; break;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001061 }
1062
Jason Huang09b73ea2020-01-08 17:52:05 +08001063 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s, family: %s, board_technology: %s\n",
1064 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 +00001065
1066 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001067 }
1068
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001069 /* 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 +00001070 only the devices that retured success*/
1071 if (num_failed_cfg_gets == BCM_MAX_DEVS_PER_LINE_CARD) {
1072 OPENOLT_LOG(ERROR, openolt_log_id, "device: Query of all the devices failed\n");
1073 return bcm_to_grpc_err(err, "device: All devices failed query");
1074 }
1075
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001076 return Status::OK;
1077}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001078
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001079Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001080 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001081 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
1082 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
1083 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001084
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001085 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001086 if (err == BCM_ERR_OK) {
1087 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001088 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001089 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1090 CreateDefaultSched(intf_id, upstream);
1091 CreateDefaultQueue(intf_id, upstream);
1092 return Status::OK;
1093 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1094 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
1095 return Status::OK;
1096 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001097 }
1098
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001099 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
1100 if (set_state) {
1101 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1102 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1103 } else {
1104 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1105 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1106 }
1107 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
1108 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001109 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err = %s\n",
1110 (set_state)?"enable":"disable", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001111 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
1112 }
1113 else {
1114 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
1115 if (set_state) {
1116 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1117 CreateDefaultSched(intf_id, upstream);
1118 CreateDefaultQueue(intf_id, upstream);
1119 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001120 }
1121
1122 return Status::OK;
1123}
1124
Elia Battiston869a5de2022-02-08 11:40:58 +01001125uint32_t GetNniSpeed_(uint32_t intf_id) {
1126 bcmos_errno err = BCM_ERR_OK;
1127
1128 uint32_t speed;
1129 err = get_nni_interface_speed((bcmolt_interface)intf_id, &speed);
1130 if (err != BCM_ERR_OK) {
1131 OPENOLT_LOG(WARNING, openolt_log_id, "Failed to read speed of NNI interface: %d\n", intf_id);
1132 return 0; //This will cause the adapter to use the default speed value
1133 }
1134
1135 return speed;
1136}
1137
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001138Status DisablePonIf_(uint32_t intf_id) {
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001139 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001140 bcmolt_pon_interface_cfg interface_obj;
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001141 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1142 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001143
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001144 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
Girish Gowdrae1db2952021-05-04 00:16:54 -07001145 BCMOLT_MSG_FIELD_GET(&interface_obj, state);
1146
1147 err = bcmolt_cfg_get(dev_id, &interface_obj.hdr);
1148 if (err != BCM_ERR_OK) {
1149 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);
1150 return bcm_to_grpc_err(err, "Failed to fetch pon port state");
1151 }
1152 if (interface_obj.data.state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1153 OPENOLT_LOG(INFO, openolt_log_id, "PON Interface already inactive, PON interface %d\n", intf_id);
1154 return Status::OK;
1155 }
1156
1157 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001158 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1159 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_DISABLE);
1160
1161 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1162 if (err != BCM_ERR_OK) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07001163 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 -05001164 return bcm_to_grpc_err(err, "Failed to disable discovery of onu");
1165 }
1166
1167 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1168 operation, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1169
1170 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1171 if (err != BCM_ERR_OK) {
1172 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 -04001173 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001174 }
1175
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001176 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled PON interface: %d\n", intf_id);
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001177 return Status::OK;
1178}
1179
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001180Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
kesavandc1f2db92020-08-31 15:32:06 +05301181 const char *vendor_id, const char *vendor_specific, uint32_t pir, bool omcc_encryption_mode) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001182 bcmos_errno err = BCM_ERR_OK;
1183 bcmolt_onu_cfg onu_cfg;
1184 bcmolt_onu_key onu_key;
1185 bcmolt_serial_number serial_number; /**< ONU serial number */
1186 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001187
Girish Gowdra24297032020-03-23 12:32:37 -07001188 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1189 bcmolt_onu_state onu_state;
1190
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001191 onu_key.onu_id = onu_id;
1192 onu_key.pon_ni = intf_id;
1193 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1194 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Girish Gowdra24297032020-03-23 12:32:37 -07001195#ifdef TEST_MODE
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001196 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1197 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1198 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1199 // of onu_cfg is passed. This is one-of case where we need to add test specific
1200 // code in production code.
1201 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Girish Gowdra24297032020-03-23 12:32:37 -07001202#else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001203 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Girish Gowdra24297032020-03-23 12:32:37 -07001204#endif
1205 OPENOLT_LOG(INFO, openolt_log_id, "Activate ONU : old state = %d, current state = %d\n",
1206 onu_cfg.data.onu_old_state, onu_cfg.data.onu_state);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001207 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001208 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) {
1209 OPENOLT_LOG(INFO, openolt_log_id, "ONU is already in ACTIVE state, \
1210not processing this request for pon_intf=%d onu_id=%d\n", intf_id, onu_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001211 return Status::OK;
Girish Gowdra24297032020-03-23 12:32:37 -07001212 } else if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_NOT_CONFIGURED &&
1213 onu_cfg.data.onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1214 // We need the ONU to be in NOT_CONFIGURED or INACTIVE state to further process the request
1215 OPENOLT_LOG(ERROR, openolt_log_id, "ONU in an invalid state to process the request, \
1216state=%d pon_intf=%d onu_id=%d\n", onu_cfg.data.onu_state, intf_id, onu_id);
1217 return bcm_to_grpc_err(err, "Failed to activate ONU, invalid ONU state");
1218 }
1219 } else {
1220 // This should never happen. BAL GET should succeed for non-existant ONUs too. The state of such ONUs will be NOT_CONFIGURED
1221 OPENOLT_LOG(ERROR, openolt_log_id, "ONU state query failed pon_intf=%d onu_id=%d\n", intf_id, onu_id);
1222 return bcm_to_grpc_err(err, "onu get failed");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001223 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001224
Girish Gowdra24297032020-03-23 12:32:37 -07001225 // If the ONU is not configured at all we need to first configure it
1226 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_NOT_CONFIGURED) {
1227 OPENOLT_LOG(INFO, openolt_log_id, "Configuring ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001228vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Girish Gowdra24297032020-03-23 12:32:37 -07001229 vendor_specific_to_str(vendor_specific).c_str(), pir);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001230
Girish Gowdra24297032020-03-23 12:32:37 -07001231 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1232 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1233 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1234 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1235 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1236 /*set burst and data profiles to fec disabled*/
Arthur Syu094df162022-04-21 17:50:06 +08001237 std::string intf_technology = intf_technologies[intf_id];
1238 if (intf_technology == "XGS-PON") {
Girish Gowdra24297032020-03-23 12:32:37 -07001239 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1240 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
Arthur Syu094df162022-04-21 17:50:06 +08001241 } else if (intf_technology == "GPON") {
Girish Gowdra24297032020-03-23 12:32:37 -07001242 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1243 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1244 }
1245 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1246 if (err != BCM_ERR_OK) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07001247 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 -07001248 return bcm_to_grpc_err(err, "Failed to configure ONU");
1249 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001250 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001251
Burak Gurdaga0523592021-02-24 15:17:47 +00001252// TODO: MOVE THIS TO A NEW METHOD
kesavandc1f2db92020-08-31 15:32:06 +05301253 if (omcc_encryption_mode == true) {
1254 // set the encryption mode for omci port id
1255 bcmolt_itupon_gem_cfg gem_cfg;
1256 bcmolt_itupon_gem_key key = {};
1257 bcmolt_gem_port_configuration configuration = {};
1258 key.pon_ni = intf_id;
1259 key.gem_port_id = onu_id;
1260 bcmolt_control_state encryption_mode;
1261 encryption_mode = BCMOLT_CONTROL_STATE_ENABLE;
1262 BCMOLT_CFG_INIT(&gem_cfg, itupon_gem, key);
1263 BCMOLT_FIELD_SET(&gem_cfg.data, itupon_gem_cfg_data, encryption_mode, encryption_mode);
1264 err = bcmolt_cfg_set(dev_id, &gem_cfg.hdr);
1265 if(err != BCM_ERR_OK) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07001266 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 +05301267 return bcm_to_grpc_err(err, "Access_Control set ITU PON OMCI Gem port failed");
1268 }
1269 }
Girish Gowdra24297032020-03-23 12:32:37 -07001270 // Now that the ONU is configured, move the ONU to ACTIVE state
1271 memset(&onu_cfg, 0, sizeof(bcmolt_onu_cfg));
1272 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1273 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1274 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
1275 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
1276 onu_state, BCMOLT_ONU_OPERATION_ACTIVE);
1277 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001278 if (err != BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001279 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 +00001280 return bcm_to_grpc_err(err, "Failed to activate ONU");
1281 }
Girish Gowdra24297032020-03-23 12:32:37 -07001282 // ONU will eventually get activated after we have submitted the operation request. The adapter will receive an asynchronous
1283 // ONU_ACTIVATION_COMPLETED_INDICATION
1284
1285 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 +00001286
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001287 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001288}
1289
Jonathan Davis70c21812018-07-19 15:32:10 -04001290Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1291 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001292 bcmos_errno err = BCM_ERR_OK;
1293 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1294 bcmolt_onu_cfg onu_cfg;
1295 bcmolt_onu_key onu_key; /**< Object key. */
1296 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001297
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001298 onu_key.onu_id = onu_id;
1299 onu_key.pon_ni = intf_id;
1300 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1301 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1302 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301303 onu_state = onu_cfg.data.onu_state;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001304 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001305 switch (onu_state) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001306 case BCMOLT_ONU_STATE_ACTIVE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001307 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001308 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001309 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1310 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1311 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001312 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 +00001313 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1314 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301315 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 +00001316 break;
1317 }
Girish Gowdra72cbee92021-11-05 15:16:18 -07001318 } else {
1319 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to deactivate ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
1320 return bcm_to_grpc_err(err, "Failed to get onu config");
Jonathan Davis70c21812018-07-19 15:32:10 -04001321 }
1322
1323 return Status::OK;
1324}
1325
1326Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001327 const char *vendor_id, const char *vendor_specific) {
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301328 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301329 bcmolt_onu_state onu_state;
Girish Gowdra72cbee92021-11-05 15:16:18 -07001330 Status st;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001331
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001332 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 -05001333 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1334
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001335 // Need to deactivate before removing it (BAL rules)
Girish Gowdra72cbee92021-11-05 15:16:18 -07001336 st = DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
1337 if (st.error_code() != grpc::StatusCode::OK) {
1338 return st;
1339 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301340
Girish Gowdra72cbee92021-11-05 15:16:18 -07001341 err = get_onu_state((bcmolt_interface)intf_id, onu_id, &onu_state);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301342 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001343 if (onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1344 OPENOLT_LOG(INFO, openolt_log_id, "waiting for onu deactivate complete response: intf_id=%d, onu_id=%d\n",
1345 intf_id, onu_id);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301346 err = wait_for_onu_deactivate_complete(intf_id, onu_id);
1347 if (err) {
1348 OPENOLT_LOG(ERROR, openolt_log_id, "failed to delete onu intf_id %d, onu_id %d\n",
1349 intf_id, onu_id);
1350 return bcm_to_grpc_err(err, "Failed to delete ONU");
1351 }
1352 }
Girish Gowdra24297032020-03-23 12:32:37 -07001353 else {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301354 OPENOLT_LOG(INFO, openolt_log_id, "Onu is Inactive, onu_id: %d, not waiting for onu deactivate complete response\n",
1355 intf_id);
1356 }
1357 }
1358 else {
1359 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch Onu status, onu_id = %d, intf_id = %d, err = %s\n",
1360 onu_id, intf_id, bcmos_strerror(err));
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301361 return bcm_to_grpc_err(err, "Failed to delete ONU");
1362 }
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001363
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001364 bcmolt_onu_cfg cfg_obj;
1365 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001366
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001367 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 -04001368 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001369
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001370 key.onu_id = onu_id;
1371 key.pon_ni = intf_id;
1372 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001373
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301374 err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001375 if (err != BCM_ERR_OK)
1376 {
Girish Gowdra72cbee92021-11-05 15:16:18 -07001377 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 -04001378 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1379 }
1380
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301381 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 +00001382 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001383}
1384
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001385#define MAX_CHAR_LENGTH 20
1386#define MAX_OMCI_MSG_LENGTH 44
1387Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001388 bcmolt_bin_str buf = {};
1389 bcmolt_onu_cpu_packets omci_cpu_packets;
1390 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001391
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001392 key.pon_ni = intf_id;
1393 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001394
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001395 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1396 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1397 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001398
1399 // ???
1400 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1401 buf.len = MAX_OMCI_MSG_LENGTH;
1402 } else {
1403 buf.len = pkt.size()/2;
1404 }
1405
1406 /* Send the OMCI packet using the BAL remote proxy API */
1407 uint16_t idx1 = 0;
1408 uint16_t idx2 = 0;
1409 uint8_t arraySend[buf.len];
1410 char str1[MAX_CHAR_LENGTH];
1411 char str2[MAX_CHAR_LENGTH];
1412 memset(&arraySend, 0, buf.len);
1413
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001414 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1415 sprintf(str1,"%c", pkt[idx1]);
1416 sprintf(str2,"%c", pkt[++idx1]);
1417 strcat(str1,str2);
1418 arraySend[idx2] = strtol(str1, NULL, 16);
1419 }
1420
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001421 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1422 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001423
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001424 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1425 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1426 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001427
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001428 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001429 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001430 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 +00001431 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001432 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001433 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 -05001434 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001435 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001436 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001437
1438 return Status::OK;
1439}
1440
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001441Status 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 +00001442 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1443 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1444 bcmolt_bin_str buf = {};
1445 bcmolt_gem_port_id gem_port_id_array[1];
1446 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001447
Craig Lutgen967a1d02018-11-27 10:41:51 -06001448 if (port_no > 0) {
1449 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001450 if (gemport_id == 0) {
1451 bcmos_fastlock_lock(&data_lock);
1452 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1453 // Pick any flow that is mapped with the same port_no.
1454 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1455 if (it != port_to_flows.end() && !it->second.empty()) {
1456 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1457 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1458 if (fit != flowid_to_gemport.end()) {
1459 found = true;
1460 gemport_id = fit->second;
1461 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001462 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001463 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001464
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001465 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001466 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 -08001467 onu_id, port_no, intf_id);
1468 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1469 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001470 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 -08001471 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001472 }
1473
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001474 gem_port_id_array[0] = gemport_id;
1475 gem_port_list.len = 1;
1476 gem_port_list.arr = gem_port_id_array;
1477 buf.len = pkt.size();
1478 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1479 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1480
1481 /* init the API struct */
1482 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1483 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1484 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1485 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1486 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1487
1488 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1489 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1490
1491 /* call API */
1492 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001493 }
1494 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001495 //TODO: Port No is 0, it is coming sender requirement.
1496 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1497 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001498 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001499 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001500
1501 return Status::OK;
1502}
1503
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001504Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001505 bcmolt_flow_key key = {}; /* declare key */
1506 bcmolt_bin_str buffer = {};
1507 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001508
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001509 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
Girish Gowdra252f4972020-09-07 21:24:01 -07001510 bcmolt_flow_id flow_id = INVALID_FLOW_ID;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001511
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001512 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1513 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1514 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1515 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1516 key.flow_id = flow_id;
1517 else {
Jason Huang09b73ea2020-01-08 17:52:05 +08001518 if (flow_id_counters) {
1519 std::map<flow_pair, int>::iterator it;
1520 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1521 int flow_index = it->first.first;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001522 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1523 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1524 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1525 key.flow_id = flow_index;
1526 break;
1527 }
1528 }
1529 }
1530 else {
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001531 OPENOLT_LOG(ERROR, openolt_log_id, "no flow id found for uplink packetout\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001532 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1533 }
1534 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001535
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001536 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001537
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001538 /* Initialize the API struct. */
1539 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001540
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001541 buffer.len = pkt.size();
1542 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1543 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1544 if (buffer.arr == NULL) {
1545 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1546 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1547 }
1548 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1549
1550 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1551 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001552 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 -05001553 return bcm_to_grpc_err(BCM_ERR_SYSCALL_ERR, "Error sending packets via nni port");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001554 } else {
1555 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1556 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001557
1558 return Status::OK;
1559}
Girish Gowdra252f4972020-09-07 21:24:01 -07001560
Burak Gurdaga0523592021-02-24 15:17:47 +00001561bool get_aes_flag_for_gem_port(const google::protobuf::Map<unsigned int, bool> &gemport_to_aes, uint32_t gemport_id) {
1562 bool aes_flag = false;
1563 for (google::protobuf::Map<unsigned int, bool>::const_iterator it=gemport_to_aes.begin(); it!=gemport_to_aes.end(); it++) {
1564 if (it->first == gemport_id) {
1565 aes_flag = it->second;
1566 break;
1567 }
1568 }
1569 return aes_flag;
1570}
1571
Girish Gowdra252f4972020-09-07 21:24:01 -07001572Status FlowAddWrapper_(const ::openolt::Flow* request) {
1573
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001574 Status st = Status::OK;
Girish Gowdra252f4972020-09-07 21:24:01 -07001575 int32_t access_intf_id = request->access_intf_id();
1576 int32_t onu_id = request->onu_id();
1577 int32_t uni_id = request->uni_id();
1578 uint32_t port_no = request->port_no();
1579 uint64_t voltha_flow_id = request->flow_id();
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001580 uint64_t symmetric_voltha_flow_id = 0;
Girish Gowdra252f4972020-09-07 21:24:01 -07001581 const std::string flow_type = request->flow_type();
1582 int32_t alloc_id = request->alloc_id();
1583 int32_t network_intf_id = request->network_intf_id();
1584 int32_t gemport_id = request->gemport_id();
1585 const ::openolt::Classifier& classifier = request->classifier();
1586 const ::openolt::Action& action = request->action();
1587 int32_t priority = request->priority();
1588 uint64_t cookie = request->cookie();
1589 int32_t group_id = request->group_id();
1590 uint32_t tech_profile_id = request->tech_profile_id();
1591 bool replicate_flow = request->replicate_flow();
1592 const google::protobuf::Map<unsigned int, unsigned int> &pbit_to_gemport = request->pbit_to_gemport();
Burak Gurdaga0523592021-02-24 15:17:47 +00001593 const google::protobuf::Map<unsigned int, bool> &gemport_to_aes = request->gemport_to_aes();
Girish Gowdra252f4972020-09-07 21:24:01 -07001594 uint16_t flow_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001595 bool enable_encryption;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001596 // When following conditions are ALL met, it qualifies as datapath flow.
1597 // 1. valid access_intf_id, onu_id, uni_id
1598 // 2. Valid tech_profile_id
1599 // 3. flow_type that is not MULTICAST
1600 // 4. Not a trap-to-host flow.
1601 bool datapathFlow = access_intf_id >= 0 && onu_id >= 0 && uni_id >= 0 && tech_profile_id > 0
1602 && flow_type != multicast && !action.cmd().trap_to_host();
1603
1604 if (datapathFlow) {
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08001605 const std::string inverse_flow_type = flow_type == upstream? downstream : upstream;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001606 symmetric_datapath_flow_id_map_key key(access_intf_id, onu_id, uni_id, tech_profile_id, inverse_flow_type);
1607 // Find the onu-uni mapping for the pon-gem key
1608 bcmos_fastlock_lock(&symmetric_datapath_flow_id_lock);
1609 auto it = symmetric_datapath_flow_id_map.find(key);
1610 bcmos_fastlock_unlock(&symmetric_datapath_flow_id_lock, 0);
1611 if (it != symmetric_datapath_flow_id_map.end()) {
1612 symmetric_voltha_flow_id = it->second;
1613 }
1614 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001615
1616 // The intf_id variable defaults to access(PON) interface ID.
1617 // For trap-from-nni flow where access interface ID is not valid , change it to NNI interface ID
1618 // This intf_id identifies the pool from which we get the flow_id
1619 uint32_t intf_id = access_intf_id;
1620 if (onu_id < 1) {
1621 onu_id = 1;
1622 }
1623 if (access_intf_id < 0) {
1624 intf_id = network_intf_id;
1625 }
1626
1627 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)
1628 // This is the case of voltha_flow_id (not symmetric_voltha_flow_id)
1629 if (is_voltha_flow_installed(voltha_flow_id)) {
1630 OPENOLT_LOG(INFO, openolt_log_id, "voltha_flow_id=%lu, already installed\n", voltha_flow_id);
1631 return ::Status(grpc::StatusCode::ALREADY_EXISTS, "voltha-flow-already-installed");
1632 }
1633
Girish Gowdra252f4972020-09-07 21:24:01 -07001634 // This is the case of symmetric_voltha_flow_id
1635 // If symmetric_voltha_flow_id is available and valid in the Flow message,
1636 // check if it is installed, and use the corresponding device_flow_id
1637 if (symmetric_voltha_flow_id > 0 && is_voltha_flow_installed(symmetric_voltha_flow_id)) { // symmetric flow found
1638 OPENOLT_LOG(INFO, openolt_log_id, "symmetric flow and the symmetric flow is installed\n");
1639 const device_flow_params *dev_fl_symm_params;
1640 dev_fl_symm_params = get_device_flow_params(symmetric_voltha_flow_id);
1641 if (dev_fl_symm_params == NULL) {
1642 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)
1643 return ::Status(grpc::StatusCode::INTERNAL, "symmetric-flow-details-not-found");
1644 }
1645
1646 if (!replicate_flow) { // No flow replication
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001647 flow_id = dev_fl_symm_params[0].flow_id;
1648 gemport_id = dev_fl_symm_params[0].gemport_id; // overwrite the gemport with symmetric flow gemport
1649 // Should be same as what is coming in this request.
1650 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
1651 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1652 cl.set_o_pbits(dev_fl_symm_params[0].pbit);
1653 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1654 flow_type, alloc_id, network_intf_id, gemport_id, cl,
1655 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
1656 if (st.error_code() != grpc::StatusCode::OK && st.error_code() != grpc::StatusCode::ALREADY_EXISTS) {
1657 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 -07001658 free_flow_id(flow_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001659 return st;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001660 }
1661
1662 device_flow dev_fl;
1663 dev_fl.is_flow_replicated = false;
1664 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1665 dev_fl.voltha_flow_id = voltha_flow_id;
Girish Gowdra72bb4652022-01-18 17:04:30 -08001666 dev_fl.flow_type = flow_type;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001667 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params));
1668 // update voltha flow to cache
1669 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
Girish Gowdra252f4972020-09-07 21:24:01 -07001670 } else { // Flow to be replicated
1671 OPENOLT_LOG(INFO, openolt_log_id,"symmetric flow and replication is needed\n");
Girish Gowdra52997cc2022-06-02 20:58:50 -07001672 if (pbit_to_gemport.size() > NUMBER_OF_PBITS) {
1673 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pbit-to-gemport map size=%lu", pbit_to_gemport.size())
1674 return ::Status(grpc::StatusCode::OUT_OF_RANGE, "pbit-to-gemport-map-len-invalid-for-flow-replication");
1675 }
1676 for (uint8_t i=0; i<pbit_to_gemport.size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07001677 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1678 flow_id = dev_fl_symm_params[i].flow_id;
1679 gemport_id = dev_fl_symm_params[i].gemport_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001680 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001681 cl.set_o_pbits(dev_fl_symm_params[i].pbit);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001682 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdrade65ab42020-12-17 23:08:43 -08001683 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001684 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001685 if (st.error_code() != grpc::StatusCode::OK && st.error_code() != grpc::StatusCode::ALREADY_EXISTS) {
1686 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);
1687 // On failure remove any successfully replicated flows installed so far for the voltha_flow_id
1688 if (i > 0) {
1689 for (int8_t j = i-1; j >= 0; j--) {
1690 flow_id = dev_fl_symm_params[j].flow_id;
1691 FlowRemove_(flow_id, flow_type);
1692 }
1693 }
Girish Gowdra72cbee92021-11-05 15:16:18 -07001694 // Note: We should not free the flow_ids here because the symmetric flow is already using that flow id.
1695 // 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 -07001696 return st;
1697 }
1698 }
1699 device_flow dev_fl;
1700 dev_fl.is_flow_replicated = true;
1701 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1702 dev_fl.voltha_flow_id = voltha_flow_id;
Girish Gowdra52997cc2022-06-02 20:58:50 -07001703 dev_fl.total_replicated_flows = pbit_to_gemport.size();
Girish Gowdra72bb4652022-01-18 17:04:30 -08001704 dev_fl.flow_type = flow_type;
Girish Gowdra52997cc2022-06-02 20:58:50 -07001705 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params)*dev_fl.total_replicated_flows);
Girish Gowdra252f4972020-09-07 21:24:01 -07001706 // update voltha flow to cache
1707 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1708 }
1709 } else { // No symmetric flow found
1710 if (!replicate_flow) { // No flow replication
1711 OPENOLT_LOG(INFO, openolt_log_id, "not a symmetric flow and replication is not needed\n");
1712 flow_id = get_flow_id();
1713 if (flow_id == INVALID_FLOW_ID) {
1714 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocated flow id for voltha-flow-id=%lu\n", voltha_flow_id);
1715 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1716 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001717 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001718 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001719 flow_type, alloc_id, network_intf_id, gemport_id, classifier,
Burak Gurdaga0523592021-02-24 15:17:47 +00001720 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001721 if (st.error_code() == grpc::StatusCode::OK) {
1722 device_flow dev_fl;
1723 dev_fl.is_flow_replicated = false;
1724 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // Invalid
1725 dev_fl.voltha_flow_id = voltha_flow_id;
Girish Gowdra72bb4652022-01-18 17:04:30 -08001726 dev_fl.flow_type = flow_type;
Girish Gowdra252f4972020-09-07 21:24:01 -07001727 dev_fl.params[0].flow_id = flow_id;
1728 dev_fl.params[0].gemport_id = gemport_id;
1729 dev_fl.params[0].pbit = classifier.o_pbits();
1730 // update voltha flow to cache
1731 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1732 } else {
1733 // Free the flow id on failure
1734 free_flow_id(flow_id);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001735 return st;
Girish Gowdra252f4972020-09-07 21:24:01 -07001736 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001737 } else { // Flow to be replicated
1738 OPENOLT_LOG(INFO, openolt_log_id,"not a symmetric flow and replication is needed\n");
Girish Gowdra52997cc2022-06-02 20:58:50 -07001739 if (pbit_to_gemport.size() > NUMBER_OF_PBITS) {
Girish Gowdra252f4972020-09-07 21:24:01 -07001740 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pbit-to-gemport map size=%lu", pbit_to_gemport.size())
1741 return ::Status(grpc::StatusCode::OUT_OF_RANGE, "pbit-to-gemport-map-len-invalid-for-flow-replication");
1742 }
Girish Gowdra52997cc2022-06-02 20:58:50 -07001743 uint16_t flow_ids[MAX_NUMBER_OF_REPLICATED_FLOWS];
Girish Gowdra252f4972020-09-07 21:24:01 -07001744 device_flow dev_fl;
Girish Gowdra52997cc2022-06-02 20:58:50 -07001745 if (get_flow_ids(pbit_to_gemport.size(), flow_ids)) {
Girish Gowdra252f4972020-09-07 21:24:01 -07001746 uint8_t cnt = 0;
1747 dev_fl.is_flow_replicated = true;
1748 dev_fl.voltha_flow_id = voltha_flow_id;
1749 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // invalid
Girish Gowdra52997cc2022-06-02 20:58:50 -07001750 dev_fl.total_replicated_flows = pbit_to_gemport.size();
Girish Gowdra72bb4652022-01-18 17:04:30 -08001751 dev_fl.flow_type = flow_type;
Girish Gowdra252f4972020-09-07 21:24:01 -07001752 for (google::protobuf::Map<unsigned int, unsigned int>::const_iterator it=pbit_to_gemport.begin(); it!=pbit_to_gemport.end(); it++) {
1753 dev_fl.params[cnt].flow_id = flow_ids[cnt];
1754 dev_fl.params[cnt].pbit = it->first;
1755 dev_fl.params[cnt].gemport_id = it->second;
1756
1757 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1758 flow_id = dev_fl.params[cnt].flow_id;
1759 gemport_id = dev_fl.params[cnt].gemport_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001760 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001761 cl.set_o_pbits(dev_fl.params[cnt].pbit);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001762 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001763 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001764 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001765 if (st.error_code() != grpc::StatusCode::OK) {
1766 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);
1767 // Remove any successfully replicated flows installed so far for the voltha_flow_id
1768 if (cnt > 0) {
1769 for (int8_t j = cnt-1; j >= 0; j--) {
1770 flow_id = dev_fl.params[j].flow_id;
1771 FlowRemove_(flow_id, flow_type);
1772 }
1773 }
1774 // Free up all the flow IDs on failure
Girish Gowdra52997cc2022-06-02 20:58:50 -07001775 free_flow_ids(pbit_to_gemport.size(), flow_ids);
Girish Gowdra252f4972020-09-07 21:24:01 -07001776 return st;
1777 }
1778 cnt++;
1779 }
1780 // On successful flow replication update voltha-flow-id to device-flow map to cache
1781 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1782 } else {
1783 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocate flow ids for replication voltha-flow-id=%lu\n", voltha_flow_id);
1784 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1785 }
1786 }
1787 }
1788
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001789 if (datapathFlow) {
1790 // Create the pon-gem to onu-uni mapping
1791 symmetric_datapath_flow_id_map_key key(access_intf_id, onu_id, uni_id, tech_profile_id, flow_type);
1792 bcmos_fastlock_lock(&symmetric_datapath_flow_id_lock);
1793 symmetric_datapath_flow_id_map[key] = voltha_flow_id;
1794 bcmos_fastlock_unlock(&symmetric_datapath_flow_id_lock, 0);
1795 }
1796
1797 return st;
Girish Gowdra252f4972020-09-07 21:24:01 -07001798}
1799
1800
Craig Lutgen967a1d02018-11-27 10:41:51 -06001801Status 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 +00001802 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001803 int32_t alloc_id, int32_t network_intf_id,
1804 int32_t gemport_id, const ::openolt::Classifier& classifier,
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001805 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie,
Burak Gurdaga0523592021-02-24 15:17:47 +00001806 int32_t group_id, uint32_t tech_profile_id, bool aes_enabled) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001807 bcmolt_flow_cfg cfg;
1808 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001809 int32_t o_vid = -1;
1810 bool single_tag = false;
1811 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001812 bcmolt_classifier c_val = { };
1813 bcmolt_action a_val = { };
1814 bcmolt_tm_queue_ref tm_val = { };
1815 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05001816 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001817
Jason Huang09b73ea2020-01-08 17:52:05 +08001818 OPENOLT_LOG(INFO, openolt_log_id, "flow add received for flow_id=%u, flow_type=%s\n", flow_id, flow_type.c_str());
1819
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001820 key.flow_id = flow_id;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08001821 if (flow_type == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001822 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08001823 } else if (flow_type == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001824 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08001825 } else if (flow_type == multicast) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001826 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001827 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001828 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001829 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001830 }
1831
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001832 BCMOLT_CFG_INIT(&cfg, flow, key);
1833 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001834
Jason Huang09b73ea2020-01-08 17:52:05 +08001835 if (action.cmd().trap_to_host()) {
Girish Gowdra1935e6a2020-10-31 21:48:22 -07001836 Status resp = handle_acl_rule_install(onu_id, flow_id, gemport_id, flow_type, access_intf_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001837 network_intf_id, classifier);
Jason Huang09b73ea2020-01-08 17:52:05 +08001838 return resp;
1839 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001840
1841 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1842
1843 if (access_intf_id >= 0 && network_intf_id >= 0) {
1844 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1845 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1846 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08001847 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1848 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001849 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1850 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1851 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1852 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1853 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001854 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001855 } else {
1856 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
1857 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001858 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001859
Burak Gurdaga0523592021-02-24 15:17:47 +00001860 if (onu_id >= ONU_ID_START) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001861 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
1862 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001863 if (gemport_id >= GEM_PORT_ID_START) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001864 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
1865 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001866 if (gemport_id >= GEM_PORT_ID_START && port_no != 0) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001867 bcmos_fastlock_lock(&data_lock);
1868 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
1869 port_to_flows[port_no].insert(key.flow_id);
1870 flowid_to_gemport[key.flow_id] = gemport_id;
1871 }
1872 else
1873 {
1874 flowid_to_port[key.flow_id] = port_no;
1875 }
1876 bcmos_fastlock_unlock(&data_lock, 0);
1877 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001878
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001879 if (priority_value >= 0) {
1880 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
1881 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301882
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001883 } else { // MULTICAST FLOW
1884 if (group_id >= 0) {
1885 BCMOLT_MSG_FIELD_SET(&cfg, group_id, group_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001886 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001887 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1888 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001889 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001890
1891 {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001892 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001893 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001894 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
1895 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001896 }
1897
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001898 if (classifier.dst_mac().size() > 0) {
1899 bcmos_mac_address d_mac = {};
1900 bcmos_mac_address_init(&d_mac);
1901 memcpy(d_mac.u8, classifier.dst_mac().data(), sizeof(d_mac.u8));
1902 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_mac %02x:%02x:%02x:%02x:%02x:%02x\n", d_mac.u8[0],
1903 d_mac.u8[1], d_mac.u8[2], d_mac.u8[3], d_mac.u8[4], d_mac.u8[5]);
1904 BCMOLT_FIELD_SET(&c_val, classifier, dst_mac, d_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001905 }
1906
Girish Gowdraf83e17a2022-02-16 16:27:00 -08001907 if (classifier.src_mac().size() > 0) {
1908 bcmos_mac_address s_mac = {};
1909 bcmos_mac_address_init(&s_mac);
1910 memcpy(s_mac.u8, classifier.src_mac().data(), sizeof(s_mac.u8));
1911 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_mac %02x:%02x:%02x:%02x:%02x:%02x\n", s_mac.u8[0],
1912 s_mac.u8[1], s_mac.u8[2], s_mac.u8[3], s_mac.u8[4], s_mac.u8[5]);
1913 BCMOLT_FIELD_SET(&c_val, classifier, src_mac, s_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001914 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001915
1916 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001917 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
1918 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001919 }
1920
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001921 if (classifier.dst_ip()) {
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08001922 bcmos_ipv4_address d_ip = {};
1923 bcmos_ipv4_address_init(&d_ip);
1924 d_ip.u32 = classifier.dst_ip();
1925 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_ip %04x\n", d_ip.u32);
1926 BCMOLT_FIELD_SET(&c_val, classifier, dst_ip, d_ip);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001927 }
1928
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08001929 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001930 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001931 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001932 }
1933 */
1934
1935 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001936 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
1937 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001938 }
1939
1940 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001941 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
1942 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001943 }
1944
1945 if (!classifier.pkt_tag_type().empty()) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001946 if (classifier.o_vid()) {
1947 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
1948 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
1949 }
1950
1951 if (classifier.i_vid()) {
1952 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
1953 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
1954 }
1955
1956 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
1957 if (classifier.pkt_tag_type().compare("untagged") == 0) {
1958 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
1959 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
1960 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
1961 single_tag = true;
1962
1963 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301964 // OpenOlt adapter will send 0xFF in case of no pbit classification
1965 // If it is any other value (0 to 7), it is for outer pbit classification.
1966 // OpenFlow protocol does not provide inner pbit classification (in case of double tagged packets),
1967 // and VOLTHA has not used any workaround to solve this problem (for ex: use metadata field).
1968 // Also there exists no use case for i-pbit classification, so we can safely ignore this for now.
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 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001972 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
1973 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001974
Jason Huang09b73ea2020-01-08 17:52:05 +08001975 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301976 // Same comments as in case of "single_tag" packets.
1977 // 0xFF means no pbit classification, otherwise a valid PCP (0 to 7).
1978 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001979 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301980 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001981 }
1982 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001983 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001984 }
1985
Jason Huang09b73ea2020-01-08 17:52:05 +08001986 const ::openolt::ActionCmd& cmd = action.cmd();
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001987
Jason Huang09b73ea2020-01-08 17:52:05 +08001988 if (cmd.add_outer_tag()) {
1989 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
1990 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001991 }
1992
Jason Huang09b73ea2020-01-08 17:52:05 +08001993 if (cmd.remove_outer_tag()) {
1994 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
1995 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
1996 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301997
Girish Gowdraf83e17a2022-02-16 16:27:00 -08001998 if (cmd.translate_outer_tag()) {
1999 OPENOLT_LOG(DEBUG, openolt_log_id, "action translate o_tag\n");
2000 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_XLATE_OUTER_TAG);
2001 }
2002
Jason Huang09b73ea2020-01-08 17:52:05 +08002003 if (action.o_vid()) {
2004 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
2005 o_vid = action.o_vid();
2006 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
2007 }
2008
2009 if (action.o_pbits()) {
2010 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
2011 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
2012 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05302013
Jason Huang09b73ea2020-01-08 17:52:05 +08002014 if (action.i_vid()) {
2015 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
2016 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
2017 }
2018
2019 if (action.i_pbits()) {
2020 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
2021 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
2022 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05302023
Jason Huang09b73ea2020-01-08 17:52:05 +08002024 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
2025
Burak Gurdaga0523592021-02-24 15:17:47 +00002026 if ((access_intf_id >= 0) && (onu_id >= ONU_ID_START)) {
Jason Huang09b73ea2020-01-08 17:52:05 +08002027 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
2028 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002029 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 +00002030
Jason Huang09b73ea2020-01-08 17:52:05 +08002031 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2032 // Queue 0 on DS subscriber scheduler
2033 tm_val.queue_id = 0;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002034
Jason Huang09b73ea2020-01-08 17:52:05 +08002035 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2036 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2037 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002038
Jason Huang09b73ea2020-01-08 17:52:05 +08002039 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2040 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2041 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002042
Jason Huang09b73ea2020-01-08 17:52:05 +08002043 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2044 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
2045 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 +00002046
Jason Huang09b73ea2020-01-08 17:52:05 +08002047 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2048 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2049 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2050 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 +00002051
Jason Huang09b73ea2020-01-08 17:52:05 +08002052 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2053 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2054 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2055 }
2056 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
2057 // NNI Scheduler ID
2058 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2059 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2060 // Queue 0 on NNI scheduler
2061 tm_val.queue_id = 0;
2062 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2063 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2064 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002065
Jason Huang09b73ea2020-01-08 17:52:05 +08002066 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 +00002067 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2068 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2069
Jason Huang09b73ea2020-01-08 17:52:05 +08002070 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2071 /* Fetch TM QMP ID mapped to US NNI scheduler */
2072 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2073 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2074 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2075 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2076 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 +00002077
Jason Huang09b73ea2020-01-08 17:52:05 +08002078 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 +00002079 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2080 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002081 }
Shad Ansari39739bc2018-09-13 21:38:37 +00002082 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302083 } else {
2084 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2085 tm_val.queue_id = 0;
2086
2087 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2088 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2089 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2090
2091 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2092 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
2093 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00002094 }
2095
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002096 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002097
Girish Gowdra252f4972020-09-07 21:24:01 -07002098#ifndef SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002099 // BAL 3.1 supports statistics only for unicast flows.
2100 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
2101 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
2102 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002103#endif // SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002104
Girish Gowdra252f4972020-09-07 21:24:01 -07002105#ifndef SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002106#ifdef FLOW_CHECKER
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002107 //Flow Checker, To avoid duplicate flow.
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002108 if (flow_id_counters != 0) {
2109 bool b_duplicate_flow = false;
Jason Huang09b73ea2020-01-08 17:52:05 +08002110 std::map<flow_pair, int>::iterator it;
2111
2112 for(it = flow_map.begin(); it != flow_map.end(); it++) {
2113 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(it->first.first, it->first.second, ONU_ID)) && \
2114 (key.flow_type == it->first.second) && \
2115 (cfg.data.svc_port_id == get_flow_status(it->first.first, it->first.second, SVC_PORT_ID)) && \
2116 (cfg.data.priority == get_flow_status(it->first.first, it->first.second, PRIORITY)) && \
2117 (cfg.data.cookie == get_flow_status(it->first.first, it->first.second, COOKIE)) && \
2118 (cfg.data.ingress_intf.intf_type == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_TYPE)) && \
2119 (cfg.data.ingress_intf.intf_id == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_ID)) && \
2120 (cfg.data.egress_intf.intf_type == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_TYPE)) && \
2121 (cfg.data.egress_intf.intf_id == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_ID)) && \
2122 (c_val.o_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_VID)) && \
2123 (c_val.o_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_PBITS)) && \
2124 (c_val.i_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_VID)) && \
2125 (c_val.i_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_PBITS)) && \
2126 (c_val.ether_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_ETHER_TYPE)) && \
2127 (c_val.ip_proto == get_flow_status(it->first.first, it->first.second, CLASSIFIER_IP_PROTO)) && \
2128 (c_val.src_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_SRC_PORT)) && \
2129 (c_val.dst_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_DST_PORT)) && \
2130 (c_val.pkt_tag_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_PKT_TAG_TYPE)) && \
2131 (cfg.data.egress_qos.type == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TYPE)) && \
2132 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_QUEUE_ID)) && \
2133 (cfg.data.egress_qos.tm_sched.id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TM_SCHED_ID)) && \
2134 (a_val.cmds_bitmask == get_flow_status(it->first.first, it->first.second, ACTION_CMDS_BITMASK)) && \
2135 (a_val.o_vid == get_flow_status(it->first.first, it->first.second, ACTION_O_VID)) && \
2136 (a_val.i_vid == get_flow_status(it->first.first, it->first.second, ACTION_I_VID)) && \
2137 (a_val.o_pbits == get_flow_status(it->first.first, it->first.second, ACTION_O_PBITS)) && \
2138 (a_val.i_pbits == get_flow_status(it->first.first, it->first.second, ACTION_I_PBITS)) && \
2139 (cfg.data.state == get_flow_status(it->first.first, it->first.second, STATE)) && \
2140 (cfg.data.group_id == get_flow_status(it->first.first, it->first.second, GROUP_ID));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002141#ifdef SHOW_FLOW_PARAM
2142 // Flow Parameter
2143 FLOW_PARAM_LOG();
2144#endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002145 if (b_duplicate_flow) {
2146 FLOW_LOG(WARNING, "Flow duplicate", 0);
2147 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
2148 }
2149 }
2150 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002151#endif // FLOW_CHECKER
2152#endif // SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002153
2154 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2155 if (err) {
2156 FLOW_LOG(ERROR, "Flow add failed", err);
2157 return bcm_to_grpc_err(err, "flow add failed");
2158 } else {
2159 FLOW_LOG(INFO, "Flow add ok", err);
2160 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002161 flow_map[std::pair<int, int>(key.flow_id,key.flow_type)] = flow_map.size();
2162 flow_id_counters = flow_map.size();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002163 bcmos_fastlock_unlock(&data_lock, 0);
Girish Gowdra252f4972020-09-07 21:24:01 -07002164
2165 }
Burak Gurdaga0523592021-02-24 15:17:47 +00002166
2167 /*
2168 Enable AES encryption on GEM ports if they are used in downstream unicast flows.
2169 Rationale: We can't do upstream encryption in GPON. This change addresses the common denominator (and also minimum viable)
2170 use case for both technologies which is downstream unicast GEM port encryption. Since the downstream traffic is inherently
2171 broadcast to all the ONUs behind a PON port, encrypting the individual subscriber traffic in this direction is important
2172 and considered good enough in terms of security (See Section 12.1 of G.984.3). For upstream unicast and downstream multicast
2173 GEM encryption, we need to make additional changes specific to XGSPON. This will be done as a future work.
2174 */
2175 if (aes_enabled && (access_intf_id >= 0) && (gemport_id >= GEM_PORT_ID_START) && (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM)) {
2176 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 +05302177 enable_encryption_for_gem_port(access_intf_id, gemport_id, board_technology);
Burak Gurdaga0523592021-02-24 15:17:47 +00002178 } else {
2179 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);
2180 }
2181
Girish Gowdra252f4972020-09-07 21:24:01 -07002182 return Status::OK;
2183}
2184
2185Status FlowRemoveWrapper_(const ::openolt::Flow* request) {
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002186 int32_t access_intf_id = request->access_intf_id();
2187 int32_t onu_id = request->onu_id();
2188 int32_t uni_id = request->uni_id();
2189 uint32_t tech_profile_id = request->tech_profile_id();
Girish Gowdra252f4972020-09-07 21:24:01 -07002190 uint64_t voltha_flow_id = request->flow_id();
2191 Status st;
2192
2193 // If Voltha flow is not installed, return fail
2194 if (! is_voltha_flow_installed(voltha_flow_id)) {
2195 OPENOLT_LOG(ERROR, openolt_log_id, "voltha_flow_id=%lu not found\n", voltha_flow_id);
2196 return ::Status(grpc::StatusCode::NOT_FOUND, "voltha-flow-not-found");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002197 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04002198
Girish Gowdra252f4972020-09-07 21:24:01 -07002199 const device_flow *dev_fl = get_device_flow(voltha_flow_id);
2200 if (dev_fl == NULL) {
2201 OPENOLT_LOG(ERROR, openolt_log_id, "device flow for voltha_flow_id=%lu in the cache is NULL\n", voltha_flow_id);
2202 return ::Status(grpc::StatusCode::INTERNAL, "device-flow-null-in-cache");
2203 }
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002204 std::string flow_type = dev_fl->flow_type;
Girish Gowdra252f4972020-09-07 21:24:01 -07002205 if (dev_fl->is_flow_replicated) {
2206 // Note: Here we are ignoring FlowRemove failures
Girish Gowdra52997cc2022-06-02 20:58:50 -07002207 for (int i=0; i<dev_fl->total_replicated_flows; i++) {
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002208 st = FlowRemove_(dev_fl->params[i].flow_id, flow_type);
Girish Gowdra252f4972020-09-07 21:24:01 -07002209 if (st.error_code() == grpc::StatusCode::OK) {
2210 free_flow_id(dev_fl->params[i].flow_id);
2211 }
2212 }
2213 } else {
2214 // Note: Here we are ignoring FlowRemove failures
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002215 st = FlowRemove_(dev_fl->params[0].flow_id, flow_type);
Girish Gowdra252f4972020-09-07 21:24:01 -07002216 if (st.error_code() == grpc::StatusCode::OK) {
2217 free_flow_id(dev_fl->params[0].flow_id);
2218 }
2219 }
2220 // remove the flow from cache on voltha flow removal
2221 remove_voltha_flow_from_cache(voltha_flow_id);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002222
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002223 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 -07002224 // Remove onu-uni mapping for the pon-gem key
2225 bcmos_fastlock_lock(&symmetric_datapath_flow_id_lock);
2226 symmetric_datapath_flow_id_map.erase(key);
2227 bcmos_fastlock_unlock(&symmetric_datapath_flow_id_lock, 0);
2228
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002229 return Status::OK;
2230}
2231
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002232Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
2233
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002234 bcmolt_flow_cfg cfg;
2235 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002236
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002237 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002238 key.flow_id = flow_id;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002239 if (flow_type == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002240 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002241 } else if (flow_type == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002242 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002243 } else if(flow_type == multicast) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002244 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002245 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002246 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002247 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
2248 }
2249
Jason Huang09b73ea2020-01-08 17:52:05 +08002250 OPENOLT_LOG(INFO, openolt_log_id, "flow remove received for flow_id=%u, flow_type=%s\n",
2251 flow_id, flow_type.c_str());
2252
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002253 bcmos_fastlock_lock(&acl_packet_trap_handler_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002254 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
2255 int32_t gemport_id = -1;
2256 int32_t intf_id = -1;
2257 int16_t acl_id = -1;
2258 if (flow_to_acl_map.count(fl_id_fl_dir) > 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002259
2260 acl_id_intf_id ac_id_if_id = flow_to_acl_map[fl_id_fl_dir];
2261 acl_id = std::get<0>(ac_id_if_id);
2262 intf_id = std::get<1>(ac_id_if_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002263 // cleanup acl only if it is a valid acl. If not valid acl, it may be datapath flow.
2264 if (acl_id >= 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002265 Status resp = handle_acl_rule_cleanup(acl_id, intf_id, flow_type);
Jason Huang09b73ea2020-01-08 17:52:05 +08002266 if (resp.ok()) {
2267 OPENOLT_LOG(INFO, openolt_log_id, "acl removed ok for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2268 flow_to_acl_map.erase(fl_id_fl_dir);
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002269
2270 // 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
2271 if (trap_to_host_pkt_info_with_vlan_for_flow_id.count(flow_id) > 0) {
2272 trap_to_host_pkt_info_with_vlan pkt_info_with_vlan = trap_to_host_pkt_info_with_vlan_for_flow_id[flow_id];
2273 // Formulate the trap_to_host_pkt_info tuple key
2274 trap_to_host_pkt_info pkt_info(std::get<0>(pkt_info_with_vlan),
2275 std::get<1>(pkt_info_with_vlan),
2276 std::get<2>(pkt_info_with_vlan),
2277 std::get<3>(pkt_info_with_vlan));
2278 // Extract the value corresponding to trap_to_host_pkt_info key from trap_to_host_vlan_ids_for_trap_to_host_pkt_info
2279 // The value is a list of vlan_ids for the given trap_to_host_pkt_info key
2280 // Remove the vlan_id from the list that corresponded to the flow being removed.
2281 if (trap_to_host_vlan_ids_for_trap_to_host_pkt_info.count(pkt_info) > 0) {
2282 trap_to_host_vlan_ids_for_trap_to_host_pkt_info[pkt_info].remove(std::get<4>(pkt_info_with_vlan));
2283 } else {
2284 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",
2285 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));
2286 }
2287
2288 } else {
2289 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);
2290 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002291 } else {
2292 OPENOLT_LOG(ERROR, openolt_log_id, "acl remove error for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2293 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002294 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002295 return resp;
2296 }
2297 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002298 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002299
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002300 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002301 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002302 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002303 flowid_to_gemport.erase(key.flow_id);
2304 port_to_flows[port_no].erase(key.flow_id);
2305 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
2306 }
2307 else
2308 {
2309 flowid_to_port.erase(key.flow_id);
2310 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002311 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002312
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002313 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002314
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002315 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002316 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07002317 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 -04002318 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
2319 }
2320
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002321 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002322 if (flow_id_counters != 0) {
2323 std::map<flow_pair, int>::iterator it;
2324 for(it = flow_map.begin(); it != flow_map.end(); it++) {
2325 if (it->first.first == flow_id && it->first.second == key.flow_type) {
2326 flow_id_counters -= 1;
2327 flow_map.erase(it);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002328 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002329 }
2330 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002331 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
2332
Jason Huang09b73ea2020-01-08 17:52:05 +08002333 flow_to_acl_map.erase(fl_id_fl_dir);
2334
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002335 bcmos_fastlock_unlock(&data_lock, 0);
2336
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002337 return Status::OK;
2338}
2339
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002340bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
2341 bcmos_errno err;
2342 bcmolt_tm_sched_cfg tm_sched_cfg;
2343 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2344 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
2345
Jason Huangbf45ffb2019-10-30 17:29:02 +08002346 //check TM scheduler has configured or not
2347 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2348 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002349 #ifdef TEST_MODE
2350 // It is impossible to mock the setting of tm_sched_cfg.data.state because
2351 // the actual bcmolt_cfg_get passes the address of tm_sched_cfg.hdr and we cannot
2352 // set the tm_sched_cfg.data.state. So a new stub function is created and address
2353 // of tm_sched_cfg is passed. This is one-of case where we need to add test specific
2354 // code in production code.
2355 err = bcmolt_cfg_get__tm_sched_stub(dev_id, &tm_sched_cfg);
2356 #else
Jason Huangbf45ffb2019-10-30 17:29:02 +08002357 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002358 #endif
Jason Huangbf45ffb2019-10-30 17:29:02 +08002359 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07002360 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 +08002361 return err;
2362 }
2363 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
2364 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
2365 return BCM_ERR_OK;
2366 }
2367
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002368 // bcmbal_tm_sched_owner
2369 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2370
2371 /**< The output of the tm_sched object instance */
2372 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
2373
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002374 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002375 // In upstream it is NNI scheduler
2376 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 -08002377 } else if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002378 // In downstream it is PON scheduler
2379 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2380 }
2381
2382 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2383
2384 // bcmbal_tm_sched_type
2385 // set the deafult policy to strict priority
2386 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2387
2388 // num_priorities: Max number of strict priority scheduling elements
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002389 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, NUM_OF_PRIORITIES);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002390
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002391 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2392 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002393 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
2394 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002395 return err;
2396 }
2397
2398 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2399 direction.c_str(), tm_sched_key.id, intf_id);
2400 return BCM_ERR_OK;
2401}
2402
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002403bcmos_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 -07002404 uint32_t alloc_id, ::tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
2405 ::tech_profile::SchedulingPolicy sched_policy, ::tech_profile::TrafficShapingInfo tf_sh_info,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002406 uint32_t tech_profile_id) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002407
2408 bcmos_errno err;
2409
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002410 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002411 bcmolt_tm_sched_cfg tm_sched_cfg;
2412 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002413 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 -04002414
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002415 // bcmbal_tm_sched_owner
2416 // In downstream it is sub_term scheduler
2417 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002418
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002419 /**< The output of the tm_sched object instance */
2420 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002421
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002422 // bcmbal_tm_sched_parent
2423 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2424 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 +00002425 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 +00002426 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 +00002427 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002428 be achieved using the' virtual' type of attachment.
2429 tm_sched_owner.u.sub_term.intf_id = intf_id;
2430 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2431 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002432
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002433 // bcmbal_tm_sched_type
2434 // set the deafult policy to strict priority
2435 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002436
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002437 // num_priorities: Max number of strict priority scheduling elements
2438 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002439
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002440 // bcmbal_tm_shaping
2441 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2442 uint32_t cir = tf_sh_info.cir();
2443 uint32_t pir = tf_sh_info.pir();
2444 uint32_t burst = tf_sh_info.pbs();
2445 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2446 cir, pir, burst);
2447 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2448 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2449 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2450 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2451 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2452 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002453 }
2454
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002455 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002456 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002457 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Girish Gowdra72cbee92021-11-05 15:16:18 -07002458intf_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, \
2459port_no, tm_sched_cfg.hdr.hdr.err_text, err);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002460 return err;
2461 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002462 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2463uni_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 -08002464
2465 } else { //upstream
Arthur Syu094df162022-04-21 17:50:06 +08002466 std::string intf_technology = intf_technologies[intf_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002467 bcmolt_itupon_alloc_cfg cfg;
2468 bcmolt_itupon_alloc_key key = { };
2469 key.pon_ni = intf_id;
2470 key.alloc_id = alloc_id;
Arthur Syu094df162022-04-21 17:50:06 +08002471 int bw_granularity = (intf_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
Burak Gurdag623fada2021-04-20 22:02:36 +00002472 /*
2473 PIR: Maximum Bandwidth
2474 CIR: Assured Bandwidth
2475 GIR: Fixed Bandwidth
2476 */
Burak Gurdag03919c72020-02-04 22:46:57 +00002477 int pir_bw = tf_sh_info.pir()*125; // conversion from kbps to bytes/sec
2478 int cir_bw = tf_sh_info.cir()*125; // conversion from kbps to bytes/sec
Burak Gurdag623fada2021-04-20 22:02:36 +00002479 int gir_bw = tf_sh_info.gir()*125; // conversion from kbps to bytes/sec
2480 int guaranteed_bw = cir_bw+gir_bw;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002481 //offset to match bandwidth granularity
2482 int offset_pir_bw = pir_bw%bw_granularity;
Burak Gurdag623fada2021-04-20 22:02:36 +00002483 int offset_gir_bw = gir_bw%bw_granularity;
2484 int offset_guaranteed_bw = guaranteed_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002485
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002486 pir_bw = pir_bw - offset_pir_bw;
Burak Gurdag623fada2021-04-20 22:02:36 +00002487 gir_bw = gir_bw - offset_gir_bw;
2488 guaranteed_bw = guaranteed_bw - offset_guaranteed_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002489
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002490 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002491
Burak Gurdag623fada2021-04-20 22:02:36 +00002492 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);
2493
2494 if (pir_bw == 0) {
2495 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be at least %d bytes/sec\n",
2496 (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2497 return BCM_ERR_PARM;
2498 } else if (pir_bw < guaranteed_bw) {
2499 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed bandwidth (%d)\n",
2500 pir_bw, guaranteed_bw);
2501 return BCM_ERR_PARM;
2502 }
2503
2504 // Setting additional bw eligibility and validating bw provisionings
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002505 switch (additional_bw) {
Burak Gurdag623fada2021-04-20 22:02:36 +00002506
2507 case tech_profile::AdditionalBW::AdditionalBW_BestEffort: //AdditionalBW_BestEffort - For T-Cont types 4 & 5
2508 if (pir_bw == guaranteed_bw) {
2509 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2510bandwidth for additional bandwidth eligibility of type Best Effort\n");
2511 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002512 }
2513 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2514 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002515
2516 case tech_profile::AdditionalBW::AdditionalBW_NA: //AdditionalBW_NA - For T-Cont types 3 & 5
2517 if (guaranteed_bw == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002518 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2519additional bandwidth eligibility of type Non-Assured (NA)\n");
2520 return BCM_ERR_PARM;
Burak Gurdag623fada2021-04-20 22:02:36 +00002521 } else if (pir_bw == guaranteed_bw) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002522 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
Burak Gurdag623fada2021-04-20 22:02:36 +00002523bandwidth for additional bandwidth eligibility of type Non-Assured\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002524 return BCM_ERR_PARM;
2525 }
2526 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2527 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002528
2529 case tech_profile::AdditionalBW::AdditionalBW_None: //AdditionalBW_None - For T-Cont types 1 & 2
2530 if (guaranteed_bw != pir_bw) {
2531 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be equal to maximum bandwidth \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002532for additional bandwidth eligibility of type None\n");
2533 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002534 }
2535 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2536 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002537
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002538 default:
Burak Gurdag623fada2021-04-20 22:02:36 +00002539 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid additional bandwidth eligibility value (%d) supplied.\n", additional_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002540 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002541 }
Burak Gurdag623fada2021-04-20 22:02:36 +00002542
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002543 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2544 in a fine granularity. */
2545 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
Burak Gurdag623fada2021-04-20 22:02:36 +00002546 /* Since we can assign minimum 64000 bytes/sec for cbr_rt_bw, we prefer assigning
2547 gir_bw to cbr_nrt_bw to allow smaller amounts.
2548 TODO: Specify CBR_RT_BW and CBR_NRT_BW separately from VOLTHA */
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002549 /* Fixed Bandwidth with no critical requirement of shaping */
Burak Gurdag623fada2021-04-20 22:02:36 +00002550 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, gir_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002551 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
Burak Gurdag623fada2021-04-20 22:02:36 +00002552 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, guaranteed_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002553 /* Maximum allocated bandwidth allowed for this alloc ID */
2554 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
Burak Gurdag623fada2021-04-20 22:02:36 +00002555
2556 if (pir_bw == gir_bw) { // T-Cont Type 1 --> set alloc type to NONE
2557 // the condition cir_bw == 0 is implicitly satistied
2558 OPENOLT_LOG(INFO, openolt_log_id, "Setting alloc type to NONE since maximum bandwidth is equal to fixed bandwidth\n");
2559 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NONE);
2560 } else { // For other T-Cont types, set alloc type to NSR. TODO: read the default from a config file.
2561 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
2562 }
2563
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002564 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002565 for skipped allocations during quiet window */
2566 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2567 /**< Allocation Profile index for CBR non-RT Bandwidth */
2568 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2569 /**< Allocation Profile index for CBR RT Bandwidth */
2570 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2571 /**< Alloc ID Weight used in case of Extended DBA mode */
2572 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2573 /**< Alloc ID Priority used in case of Extended DBA mode */
2574 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2575 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002576
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302577 bcmolt_onu_state onu_state;
2578 bool wait_for_alloc_cfg_cmplt = false;
2579 err = get_onu_state((bcmolt_interface)intf_id, (bcmolt_onu_id)onu_id, &onu_state);
2580 if (err) {
2581 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch onu status, intf_id = %d, onu_id = %d, err = %s\n",
2582 intf_id, onu_id, bcmos_strerror(err));
2583 return err;
2584 } else if (onu_state == BCMOLT_ONU_STATE_ACTIVE) {
2585 wait_for_alloc_cfg_cmplt = true;
2586 }
2587
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002588 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002589 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002590 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 -07002591port_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 -08002592 return err;
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302593 } else if (wait_for_alloc_cfg_cmplt) {
2594 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
2595 if (err) {
2596 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 +05302597port_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 +05302598 return err;
Girish Gowdra72cbee92021-11-05 15:16:18 -07002599 }
2600 } else {
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302601 OPENOLT_LOG(INFO, openolt_log_id, "onu not active, not waiting for alloc cfg complete, onu_state = %d, intf = %d, onu=%d\n",
2602 onu_state, intf_id, onu_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302603 }
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302604
Girish Gowdra96461052019-11-22 20:13:59 +05302605 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
2606port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
2607
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002608 }
2609
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002610 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002611}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002612
Girish Gowdra252f4972020-09-07 21:24:01 -07002613Status CreateTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002614 uint32_t intf_id = traffic_scheds->intf_id();
2615 uint32_t onu_id = traffic_scheds->onu_id();
2616 uint32_t uni_id = traffic_scheds->uni_id();
2617 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002618 std::string direction;
2619 unsigned int alloc_id;
Girish Gowdra252f4972020-09-07 21:24:01 -07002620 ::tech_profile::SchedulerConfig sched_config;
2621 ::tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002622 uint32_t priority;
2623 uint32_t weight;
Girish Gowdra252f4972020-09-07 21:24:01 -07002624 ::tech_profile::SchedulingPolicy sched_policy;
2625 ::tech_profile::TrafficShapingInfo traffic_shaping_info;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002626 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002627 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002628
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002629 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002630 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002631
2632 direction = GetDirection(traffic_sched.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002633 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002634 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002635 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002636
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002637 alloc_id = traffic_sched.alloc_id();
2638 sched_config = traffic_sched.scheduler();
2639 additional_bw = sched_config.additional_bw();
2640 priority = sched_config.priority();
2641 weight = sched_config.weight();
2642 sched_policy = sched_config.sched_policy();
2643 traffic_shaping_info = traffic_sched.traffic_shaping_info();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002644 tech_profile_id = traffic_sched.tech_profile_id();
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002645 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002646 sched_policy, traffic_shaping_info, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002647 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002648 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002649 return bcm_to_grpc_err(err, "Failed to create scheduler");
2650 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002651 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002652 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002653}
Jonathan Davis70c21812018-07-19 15:32:10 -04002654
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002655bcmos_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 -04002656
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002657 bcmos_errno err;
Girish Gowdra72cbee92021-11-05 15:16:18 -07002658 bcmolt_onu_state onu_state;
Girish Gowdra96461052019-11-22 20:13:59 +05302659 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002660
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002661 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002662 bcmolt_itupon_alloc_cfg cfg;
2663 bcmolt_itupon_alloc_key key = { };
2664 key.pon_ni = intf_id;
2665 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302666 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002667
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302668 bcmolt_onu_state onu_state;
2669 bool wait_for_alloc_cfg_cmplt = false;
2670 err = get_onu_state((bcmolt_interface)intf_id, (bcmolt_onu_id)onu_id, &onu_state);
2671 if (err) {
2672 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch onu status, intf_id = %d, onu_id = %d, err = %s\n",
2673 intf_id, onu_id, bcmos_strerror(err));
2674 return err;
2675 } else if (onu_state == BCMOLT_ONU_STATE_ACTIVE) {
2676 wait_for_alloc_cfg_cmplt = true;
2677 }
2678
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002679 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002680 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2681 if (err) {
Girish Gowdra72cbee92021-11-05 15:16:18 -07002682 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s (%d)\n",
2683 direction.c_str(), intf_id, alloc_id, cfg.hdr.hdr.err_text, err);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002684 return err;
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302685 } else if (wait_for_alloc_cfg_cmplt) {
2686 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2687 if (err) {
2688 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2689pon_intf %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,intf_id,alloc_id, bcmos_strerror(err));
2690 return err;
2691 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302692 } else {
Girish Gowdracdd5e5f2021-12-05 16:48:08 +05302693 OPENOLT_LOG(INFO, openolt_log_id, "onu not active, not waiting for alloc cfg complete, onu_state = %d, intf = %d, onu=%d\n",
2694 onu_state, intf_id, onu_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302695 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002696 } else if (direction == downstream) {
2697 bcmolt_tm_sched_cfg cfg;
2698 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002699
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002700 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2701 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302702 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002703 } else {
2704 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2705 return BCM_ERR_OK;
2706 }
Girish Gowdra96461052019-11-22 20:13:59 +05302707
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002708 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2709 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2710 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002711 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
Girish Gowdra72cbee92021-11-05 15:16:18 -07002712intf_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 +00002713 return err;
2714 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002715 }
2716
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002717 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d, tech_profile_id %d\n",
2718 direction.c_str(), sched_id, intf_id, onu_id, tech_profile_id);
2719 free_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002720 return BCM_ERR_OK;
2721}
2722
Girish Gowdra252f4972020-09-07 21:24:01 -07002723Status RemoveTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002724 uint32_t intf_id = traffic_scheds->intf_id();
2725 uint32_t onu_id = traffic_scheds->onu_id();
2726 uint32_t uni_id = traffic_scheds->uni_id();
2727 std::string direction;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002728 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002729 bcmos_errno err;
2730
2731 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002732 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002733
2734 direction = GetDirection(traffic_sched.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002735 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002736 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002737 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002738
2739 int alloc_id = traffic_sched.alloc_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002740 int tech_profile_id = traffic_sched.tech_profile_id();
2741 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002742 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002743 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002744 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2745 }
2746 }
2747 return Status::OK;
2748}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002749
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002750bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2751 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002752 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002753 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2754 bcmolt_tm_qmp_key tm_qmp_key;
2755 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002756
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002757 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2758 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002759 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed tm queue mapping profile count is 16.\n");
2760 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002761 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002762
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002763 tm_qmp_key.id = tm_qmp_id;
2764 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2765 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2766 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002767
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002768 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2769 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2770 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002771 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2772 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002773
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002774 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002775 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002776 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2777 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002778 return err;
2779 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002780
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002781 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2782 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002783 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002784}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002785
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002786bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2787 bcmos_errno err;
2788 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2789 bcmolt_tm_qmp_key tm_qmp_key;
2790 tm_qmp_key.id = tm_qmp_id;
2791
2792 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2793 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2794 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002795 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2796 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002797 return err;
2798 }
2799
2800 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2801 tm_qmp_key.id);
2802 return BCM_ERR_OK;
2803}
2804
2805bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2806 bcmos_errno err;
2807
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002808 /* Create default queues on the given PON/NNI scheduler */
2809 for (int queue_id = 0; queue_id < NUMBER_OF_DEFAULT_INTERFACE_QUEUES; queue_id++) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002810 bcmolt_tm_queue_cfg tm_queue_cfg;
2811 bcmolt_tm_queue_key tm_queue_key = {};
2812 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2813 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002814 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2815 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2816 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002817
2818 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2819 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2820 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2821
2822 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2823 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002824 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", \
2825 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 +00002826 return err;
2827 }
2828
2829 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2830 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2831 }
2832 return BCM_ERR_OK;
2833}
2834
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002835bcmos_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 +00002836 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 +00002837 bcmos_errno err;
2838 bcmolt_tm_queue_cfg cfg;
2839 bcmolt_tm_queue_key key = { };
2840 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 +00002841gemport_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 +00002842
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002843 key.sched_id = (direction == upstream) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002844 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002845
2846 if (priority > 7) {
2847 return BCM_ERR_RANGE;
2848 }
2849
2850 /* FIXME: The upstream queues have to be created once only.
2851 The upstream queues on the NNI scheduler are shared by all subscribers.
2852 When the first scheduler comes in, the queues get created, and are re-used by all others.
2853 Also, these queues should be present until the last subscriber exits the system.
2854 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2855
2856 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2857 for each GEM in TECH PROFILE */
2858 key.id = queue_id_list[priority];
2859
2860 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2861 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2862 key.id = 0;
2863 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2864 }
2865 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2866 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2867 }
2868 else {
2869 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2870 }
2871
2872 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2873
2874 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2875 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
Girish Gowdra5287fde2021-07-31 00:41:45 +00002876 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002877
2878 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2879 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002880 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
Girish Gowdra72cbee92021-11-05 15:16:18 -07002881sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, tech_profile_id %d, err = %s (%d)\n", \
2882 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 +00002883 return err;
2884 }
2885
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302886 if (direction == upstream || direction == downstream) {
Thiyagarajan Subramani19168f52021-05-25 23:26:41 +05302887 Status st = install_gem_port(access_intf_id, onu_id, uni_id, gemport_id, board_technology);
Girish Gowdra252f4972020-09-07 21:24:01 -07002888 if (st.error_code() != grpc::StatusCode::ALREADY_EXISTS && st.error_code() != grpc::StatusCode::OK) {
2889 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);
2890 return BCM_ERR_INTERNAL;
2891 }
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002892 if (direction == upstream) {
2893 // Create the pon-gem to onu-uni mapping
2894 pon_gem pg(access_intf_id, gemport_id);
2895 onu_uni ou(onu_id, uni_id);
2896 bcmos_fastlock_lock(&pon_gem_to_onu_uni_map_lock);
2897 pon_gem_to_onu_uni_map[pg] = ou;
2898 bcmos_fastlock_unlock(&pon_gem_to_onu_uni_map_lock, 0);
2899 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002900 }
2901
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002902 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 +00002903intf_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 +00002904 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002905}
2906
Girish Gowdra252f4972020-09-07 21:24:01 -07002907Status CreateTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002908 uint32_t intf_id = traffic_queues->intf_id();
2909 uint32_t onu_id = traffic_queues->onu_id();
2910 uint32_t uni_id = traffic_queues->uni_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002911 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002912 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002913 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002914 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002915 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 +00002916
2917 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2918 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2919 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2920 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002921 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002922
2923 direction = GetDirection(traffic_queue.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002924 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002925 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002926 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002927
2928 queues_priority_q[i] = traffic_queue.priority();
2929 queues_pbit_map[i] = traffic_queue.pbit_map();
2930 }
2931
2932 std::vector<uint32_t> tmq_map_profile(8, 0);
2933 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2934 queues_priority_q, COUNT_OF(queues_priority_q));
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002935 sched_id = (direction == upstream) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002936 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002937
2938 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2939 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002940 err = CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2941 if (err != BCM_ERR_OK) {
2942 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2943 return bcm_to_grpc_err(err, "Failed to create tm queue mapping profile");
2944 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002945 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2946 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2947 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2948 }
2949 }
2950
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002951 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002952 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002953
2954 direction = GetDirection(traffic_queue.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002955 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002956 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08002957 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002958
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002959 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 +00002960
Girish Gowdruf26cf882019-05-01 23:47:58 -07002961 // If the queue exists already, lets not return failure and break the loop.
2962 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002963 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002964 return bcm_to_grpc_err(err, "Failed to create queue");
2965 }
2966 }
2967 return Status::OK;
2968}
2969
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002970bcmos_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 +00002971 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 +00002972 bcmolt_tm_queue_cfg cfg;
2973 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002974 bcmos_errno err;
2975
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302976 // Gemports are bi-directional (except in multicast case). We create the gem port when we create the
2977 // upstream/downstream queue (see CreateQueue function) and it makes sense to delete them when remove the queues.
2978 // For multicast case we do not manage the install/remove of gem port in agent application. It is managed by BAL.
2979 if (direction == upstream || direction == downstream) {
Thiyagarajan Subramani19168f52021-05-25 23:26:41 +05302980 Status st = remove_gem_port(access_intf_id, onu_id, uni_id, gemport_id, board_technology);
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302981 if (st.error_code() != grpc::StatusCode::OK) {
2982 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 -07002983 // We should further cleanup proceed, do not return error yet..
2984 // return BCM_ERR_INTERNAL;
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302985 }
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002986 if (direction == upstream) {
2987 // Remove the pon-gem to onu-uni mapping
2988 pon_gem pg(access_intf_id, gemport_id);
2989 bcmos_fastlock_lock(&pon_gem_to_onu_uni_map_lock);
2990 pon_gem_to_onu_uni_map.erase(pg);
2991 bcmos_fastlock_unlock(&pon_gem_to_onu_uni_map_lock, 0);
2992 }
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302993 }
2994
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002995 if (direction == downstream) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002996 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2997 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 +00002998 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002999 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003000 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 -08003001 return BCM_ERR_OK;
3002 }
3003 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003004 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
3005 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003006 return BCM_ERR_OK;
3007 }
3008
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003009 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
3010 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
3011 // Reset the queue id to 0 when using fixed queue.
3012 key.id = 0;
3013 }
3014 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
3015 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
3016 }
3017 else {
3018 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
3019 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003020
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003021 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
3022 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003023 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003024 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 -07003025tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s (%d)\n",
3026 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 -08003027 return err;
3028 }
3029
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003030 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
3031intf_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 -08003032
3033 return BCM_ERR_OK;
3034}
3035
Girish Gowdra252f4972020-09-07 21:24:01 -07003036Status RemoveTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003037 uint32_t intf_id = traffic_queues->intf_id();
3038 uint32_t onu_id = traffic_queues->onu_id();
3039 uint32_t uni_id = traffic_queues->uni_id();
3040 uint32_t port_no = traffic_queues->port_no();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00003041 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003042 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003043 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003044 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003045 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 -07003046 Status ret_code = Status::OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003047
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003048 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07003049 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003050
3051 direction = GetDirection(traffic_queue.direction());
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08003052 if (direction == "direction-not-supported") {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003053 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08003054 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003055
Burak Gurdag2f2618c2020-04-23 13:20:30 +00003056 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 -08003057 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003058 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdra72cbee92021-11-05 15:16:18 -07003059 ret_code = bcm_to_grpc_err(err, "Failed to remove one or more queues");
3060 // Do not return here. We should continue to remove the remaining queues and its associated gem ports
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003061 }
Jonathan Davis70c21812018-07-19 15:32:10 -04003062 }
3063
Girish Gowdrafc6c0bf2022-01-28 18:31:30 -08003064 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE && (direction == upstream || \
3065 direction == downstream && is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id))) {
3066 sched_id = (direction == upstream) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00003067 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003068
3069 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
3070 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05003071 err = RemoveTrafficQueueMappingProfile(tm_qmp_id);
3072 if (err != BCM_ERR_OK) {
3073 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, err = %s\n", bcmos_strerror(err));
3074 return bcm_to_grpc_err(err, "Failed to remove tm queue mapping profile");
3075 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003076 }
3077 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003078 clear_qos_type(intf_id, onu_id, uni_id);
Girish Gowdra72cbee92021-11-05 15:16:18 -07003079 return ret_code;
Jonathan Davis70c21812018-07-19 15:32:10 -04003080}
Jason Huangbf45ffb2019-10-30 17:29:02 +08003081
Girish Gowdra252f4972020-09-07 21:24:01 -07003082Status PerformGroupOperation_(const ::openolt::Group *group_cfg) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003083
3084 bcmos_errno err;
3085 bcmolt_group_key key = {};
3086 bcmolt_group_cfg grp_cfg_obj;
3087 bcmolt_group_members_update grp_mem_upd;
3088 bcmolt_members_update_command grp_mem_upd_cmd;
3089 bcmolt_group_member_info member_info = {};
3090 bcmolt_group_member_info_list_u8 members = {};
3091 bcmolt_intf_ref interface_ref = {};
3092 bcmolt_egress_qos egress_qos = {};
3093 bcmolt_tm_sched_ref tm_sched_ref = {};
3094 bcmolt_action a_val = {};
3095
3096 uint32_t group_id = group_cfg->group_id();
3097
3098 OPENOLT_LOG(INFO, openolt_log_id, "PerformGroupOperation request received for Group %d\n", group_id);
3099
3100 if (group_id >= 0) {
3101 key.id = group_id;
3102 }
3103 else {
3104 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
3105 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
3106 }
3107
3108 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3109 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
3110
3111 OPENOLT_LOG(INFO, openolt_log_id, "Checking if Group %d exists...\n",group_id);
3112
3113 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
3114 if (err != BCM_ERR_OK) {
3115 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
3116 return bcm_to_grpc_err(err, "Error in querying group");
3117 }
3118
3119 members.len = group_cfg->members_size();
3120
3121 // IMPORTANT: A member cannot be added to a group if the group type is not determined.
3122 // Group type is determined after a flow is assigned to it.
3123 // Therefore, a group must be created first, then a flow (with multicast type) must be assigned to it.
3124 // Only then we can add members to the group.
3125
3126 // if group does not exist, create it and return.
3127 if (grp_cfg_obj.data.state == BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
3128
3129 if (members.len != 0) {
3130 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);
3131 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Non-empty member list given for non-existent group");
3132 } else {
3133
3134 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3135 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, cookie, key.id);
3136
3137 /* Setting group actions and action parameters, if any.
3138 Only remove_outer_tag and translate_inner_tag actions and i_vid action parameter
3139 are supported for multicast groups in BAL 3.1.
3140 */
3141 const ::openolt::Action& action = group_cfg->action();
3142 const ::openolt::ActionCmd &cmd = action.cmd();
3143
3144 bcmolt_action_cmd_id cmd_bmask = BCMOLT_ACTION_CMD_ID_NONE;
3145 if (cmd.remove_outer_tag()) {
3146 OPENOLT_LOG(INFO, openolt_log_id, "Action remove_outer_tag applied to Group %d.\n", group_id);
3147 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
3148 }
3149
3150 if (cmd.translate_inner_tag()) {
3151 OPENOLT_LOG(INFO, openolt_log_id, "Action translate_inner_tag applied to Group %d.\n", group_id);
3152 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG);
3153 }
3154
3155 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, cmd_bmask);
3156
3157 if (action.i_vid()) {
3158 OPENOLT_LOG(INFO, openolt_log_id, "Setting action parameter i_vid=%d for Group %d.\n", action.i_vid(), group_id);
3159 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
3160 }
3161
3162 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, action, a_val);
3163
3164 // Create group
3165 err = bcmolt_cfg_set(dev_id, &(grp_cfg_obj.hdr));
3166
3167 if (BCM_ERR_OK != err) {
3168 BCM_LOG(ERROR, openolt_log_id, "Failed to create Group %d, err = %s (%d)\n", key.id, bcmos_strerror(err), err);
3169 return bcm_to_grpc_err(err, "Error in creating group");
3170 }
3171
3172 BCM_LOG(INFO, openolt_log_id, "Group %d has been created and configured with empty member list.\n", key.id);
3173 return Status::OK;
3174 }
3175 }
3176
3177 // The group already exists. Continue configuring it according to the update member command.
3178
3179 OPENOLT_LOG(INFO, openolt_log_id, "Configuring existing Group %d.\n",group_id);
3180
3181 // MEMBER LIST CONSTRUCTION
3182 // Note that members.len can be 0 here. if the group already exists and the command is SET then sending
3183 // empty list to the group is a legit operation and this actually empties the member list.
3184 members.arr = (bcmolt_group_member_info*)bcmos_calloc((members.len)*sizeof(bcmolt_group_member_info));
3185
3186 if (!members.arr) {
3187 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to allocate memory for group member list.\n");
3188 return grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "Memory exhausted during member list creation");
3189 }
3190
3191 /* SET GROUP MEMBERS UPDATE COMMAND */
Girish Gowdra252f4972020-09-07 21:24:01 -07003192 ::openolt::Group::GroupMembersCommand command = group_cfg->command();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003193 switch(command) {
Girish Gowdra252f4972020-09-07 21:24:01 -07003194 case ::openolt::Group::SET_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003195 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_SET;
3196 OPENOLT_LOG(INFO, openolt_log_id, "Setting %d members for Group %d.\n", members.len, group_id);
3197 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003198 case ::openolt::Group::ADD_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003199 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_ADD;
3200 OPENOLT_LOG(INFO, openolt_log_id, "Adding %d members to Group %d.\n", members.len, group_id);
3201 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003202 case ::openolt::Group::REMOVE_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003203 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_REMOVE;
3204 OPENOLT_LOG(INFO, openolt_log_id, "Removing %d members from Group %d.\n", members.len, group_id);
3205 break;
3206 default :
3207 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid value %d for group member command.\n", command);
3208 bcmos_free(members.arr);
3209 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group member command");
3210 }
3211
3212 // SET MEMBERS LIST
3213 for (int i = 0; i < members.len; i++) {
3214
Girish Gowdra252f4972020-09-07 21:24:01 -07003215 if (command == ::openolt::Group::REMOVE_MEMBERS) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003216 OPENOLT_LOG(INFO, openolt_log_id, "Removing group member %d from group %d\n",i,key.id);
3217 } else {
3218 OPENOLT_LOG(INFO, openolt_log_id, "Adding group member %d to group %d\n",i,key.id);
3219 }
3220
Girish Gowdra252f4972020-09-07 21:24:01 -07003221 ::openolt::GroupMember *member = (::openolt::GroupMember *) &group_cfg->members()[i];
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003222
3223 // Set member interface type
Girish Gowdra252f4972020-09-07 21:24:01 -07003224 ::openolt::GroupMember::InterfaceType if_type = member->interface_type();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003225 switch(if_type){
Girish Gowdra252f4972020-09-07 21:24:01 -07003226 case ::openolt::GroupMember::PON :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003227 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_PON);
3228 OPENOLT_LOG(INFO, openolt_log_id, "Interface type PON is assigned to GroupMember %d\n",i);
3229 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003230 case ::openolt::GroupMember::EPON_1G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003231 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_1_G);
3232 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_1G is assigned to GroupMember %d\n",i);
3233 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003234 case ::openolt::GroupMember::EPON_10G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003235 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_10_G);
3236 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_10G is assigned to GroupMember %d\n",i);
3237 break;
3238 default :
3239 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid interface type value %d for GroupMember %d.\n",if_type,i);
3240 bcmos_free(members.arr);
3241 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface type for a group member");
3242 }
3243
3244 // Set member interface id
3245 if (member->interface_id() >= 0) {
3246 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_id, member->interface_id());
3247 OPENOLT_LOG(INFO, openolt_log_id, "Interface %d is assigned to GroupMember %d\n", member->interface_id(), i);
3248 } else {
3249 bcmos_free(members.arr);
3250 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface id for a group member");
3251 }
3252
3253 // Set member interface_ref
3254 BCMOLT_FIELD_SET(&member_info, group_member_info, intf, interface_ref);
3255
3256 // Set member gem_port_id. This must be a multicast gemport.
3257 if (member->gem_port_id() >= 0) {
3258 BCMOLT_FIELD_SET(&member_info, group_member_info, svc_port_id, member->gem_port_id());
3259 OPENOLT_LOG(INFO, openolt_log_id, "GEM Port %d is assigned to GroupMember %d\n", member->gem_port_id(), i);
3260 } else {
3261 bcmos_free(members.arr);
3262 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid gem port id for a group member");
3263 }
3264
3265 // Set member scheduler id and queue_id
3266 uint32_t tm_sched_id = get_default_tm_sched_id(member->interface_id(), downstream);
3267 OPENOLT_LOG(INFO, openolt_log_id, "Scheduler %d is assigned to GroupMember %d\n", tm_sched_id, i);
3268 BCMOLT_FIELD_SET(&tm_sched_ref, tm_sched_ref, id, tm_sched_id);
3269 BCMOLT_FIELD_SET(&egress_qos, egress_qos, tm_sched, tm_sched_ref);
3270
3271 // We assume that all multicast traffic destined to a PON port is using the same fixed queue.
3272 uint32_t tm_queue_id;
3273 if (member->priority() >= 0 && member->priority() < NUMBER_OF_DEFAULT_INTERFACE_QUEUES) {
3274 tm_queue_id = queue_id_list[member->priority()];
3275 OPENOLT_LOG(INFO, openolt_log_id, "Queue %d is assigned to GroupMember %d\n", tm_queue_id, i);
3276 BCMOLT_FIELD_SET(&egress_qos, egress_qos, type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
3277 BCMOLT_FIELD_SET(&egress_qos.u.fixed_queue, egress_qos_fixed_queue, queue_id, tm_queue_id);
3278 } else {
3279 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid fixed queue priority/ID %d for GroupMember %d\n", member->priority(), i);
3280 bcmos_free(members.arr);
3281 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid queue priority for a group member");
3282 }
3283
3284 BCMOLT_FIELD_SET(&member_info, group_member_info, egress_qos, egress_qos);
3285 BCMOLT_ARRAY_ELEM_SET(&(members), i, member_info);
3286 }
3287
3288 BCMOLT_OPER_INIT(&grp_mem_upd, group, members_update, key);
3289 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.members, members);
3290 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.command, grp_mem_upd_cmd);
3291
3292 err = bcmolt_oper_submit(dev_id, &(grp_mem_upd.hdr));
3293 bcmos_free(members.arr);
3294
3295 if (BCM_ERR_OK != err) {
3296 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);
3297 return bcm_to_grpc_err(err, "Failed to submit members update operation for the group");
3298 }
3299
3300 OPENOLT_LOG(INFO, openolt_log_id, "Successfully submitted members update operation for Group %d\n", key.id);
3301
3302 return Status::OK;
3303}
Burak Gurdageb4ca2e2020-06-15 07:48:26 +00003304
3305Status DeleteGroup_(uint32_t group_id) {
3306
3307 bcmos_errno err = BCM_ERR_OK;
3308 bcmolt_group_cfg grp_cfg_obj;
3309 bcmolt_group_key key = {};
3310
3311
3312 OPENOLT_LOG(INFO, openolt_log_id, "Delete request received for group %d\n", group_id);
3313
3314 if (group_id >= 0) {
3315 key.id = group_id;
3316 } else {
3317 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
3318 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
3319 }
3320
3321 /* init the BAL INIT API */
3322 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3323
3324 OPENOLT_LOG(DEBUG, openolt_log_id, "Checking if group %d exists...\n",group_id);
3325
3326 // CONFIGURE GROUP MEMBERS
3327 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
3328 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
3329
3330 if (err != BCM_ERR_OK) {
3331 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
3332 return bcm_to_grpc_err(err, "Error in querying group");
3333 }
3334
3335 if (grp_cfg_obj.data.state != BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
3336 OPENOLT_LOG(DEBUG, openolt_log_id, "Group %d exists. Will be deleted.\n",group_id);
3337 err = bcmolt_cfg_clear(dev_id, &(grp_cfg_obj.hdr));
3338 if (err != BCM_ERR_OK) {
3339 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d cannot be deleted err = %s (%d).\n", group_id, bcmos_strerror(err), err);
3340 return bcm_to_grpc_err(err, "Failed to delete group");;
3341 }
3342 } else {
3343 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d does not exist.\n", group_id);
3344 return Status(grpc::StatusCode::NOT_FOUND, "Group not found");
3345 }
3346
3347 OPENOLT_LOG(INFO, openolt_log_id, "Group %d has been deleted successfully.\n", group_id);
3348 return Status::OK;
Jason Huang1d9cfce2020-05-20 22:58:47 +08003349}
3350
Girish Gowdra252f4972020-09-07 21:24:01 -07003351Status GetLogicalOnuDistanceZero_(uint32_t intf_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003352 bcmos_errno err = BCM_ERR_OK;
3353 uint32_t mld = 0;
3354 double LD0;
3355
3356 err = getOnuMaxLogicalDistance(intf_id, &mld);
3357 if (err != BCM_ERR_OK) {
3358 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3359 }
3360
3361 LD0 = LOGICAL_DISTANCE(mld*1000, MINIMUM_ONU_RESPONSE_RANGING_TIME, ONU_BIT_TRANSMISSION_DELAY);
3362 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance zero is %f, (PON %d)\n", LD0, intf_id);
3363 response->set_intf_id(intf_id);
3364 response->set_logical_onu_distance_zero(LD0);
3365
3366 return Status::OK;
3367}
3368
Girish Gowdra252f4972020-09-07 21:24:01 -07003369Status GetLogicalOnuDistance_(uint32_t intf_id, uint32_t onu_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003370 bcmos_errno err = BCM_ERR_OK;
3371 bcmolt_itu_onu_params itu = {};
3372 bcmolt_onu_cfg onu_cfg;
3373 bcmolt_onu_key onu_key = {};
3374 uint32_t mld = 0;
3375 double LDi;
3376
3377 onu_key.pon_ni = intf_id;
3378 onu_key.onu_id = onu_id;
3379
3380 err = getOnuMaxLogicalDistance(intf_id, &mld);
3381 if (err != BCM_ERR_OK) {
3382 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3383 }
3384
3385 /* Initialize the API struct. */
3386 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
3387 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
3388 BCMOLT_FIELD_SET_PRESENT(&itu, itu_onu_params, ranging_time);
3389 BCMOLT_FIELD_SET(&onu_cfg.data, onu_cfg_data, itu, itu);
3390 #ifdef TEST_MODE
3391 // It is impossible to mock the setting of onu_cfg.data.onu_state because
3392 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
3393 // set the onu_cfg.data.onu_state. So a new stub function is created and address
3394 // of onu_cfg is passed. This is one-of case where we need to add test specific
3395 // code in production code.
3396 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
3397 #else
3398 /* Call API function. */
3399 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
3400 #endif
3401 if (err != BCM_ERR_OK) {
3402 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);
3403 return bcm_to_grpc_err(err, "Failed to retrieve ONU ranging time");
3404 }
3405
3406 if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_ACTIVE) {
3407 OPENOLT_LOG(ERROR, openolt_log_id, "ONU is not yet activated (PON %d, ONU id %d)\n", intf_id, onu_id);
3408 return bcm_to_grpc_err(BCM_ERR_PARM, "ONU is not yet activated\n");
3409 }
3410
3411 LDi = LOGICAL_DISTANCE(mld*1000, onu_cfg.data.itu.ranging_time, ONU_BIT_TRANSMISSION_DELAY);
3412 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance is %f, (PON %d, ONU id %d)\n", LDi, intf_id, onu_id);
3413 response->set_intf_id(intf_id);
3414 response->set_onu_id(onu_id);
3415 response->set_logical_onu_distance(LDi);
3416
3417 return Status::OK;
3418}
Burak Gurdag74e3ab82020-12-17 13:35:06 +00003419
3420Status GetOnuStatistics_(uint32_t intf_id, uint32_t onu_id, openolt::OnuStatistics* onu_stats) {
3421 bcmos_errno err;
3422
3423 err = get_onu_statistics((bcmolt_interface_id)intf_id, (bcmolt_onu_id)onu_id, onu_stats);
3424
3425 if (err != BCM_ERR_OK) {
3426 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));
3427 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of ONU statistics failed");
3428 }
3429
3430 OPENOLT_LOG(INFO, openolt_log_id, "retrieved ONU statistics for PON ID = %d, ONU ID = %d\n", (int)intf_id, (int)onu_id);
3431 return Status::OK;
3432}
3433
3434Status GetGemPortStatistics_(uint32_t intf_id, uint32_t gemport_id, openolt::GemPortStatistics* gemport_stats) {
3435 bcmos_errno err;
3436
3437 err = get_gemport_statistics((bcmolt_interface_id)intf_id, (bcmolt_gem_port_id)gemport_id, gemport_stats);
3438
3439 if (err != BCM_ERR_OK) {
3440 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));
3441 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of GEMPORT statistics failed");
3442 }
3443
3444 OPENOLT_LOG(INFO, openolt_log_id, "retrieved GEMPORT statistics for PON ID = %d, GEMPORT ID = %d\n", (int)intf_id, (int)gemport_id);
3445 return Status::OK;
3446}
Orhan Kupusogluec57af02021-05-12 12:38:17 +00003447
3448Status GetPonRxPower_(uint32_t intf_id, uint32_t onu_id, openolt::PonRxPowerData* response) {
3449 bcmos_errno err = BCM_ERR_OK;
3450
3451 // check the PON intf id
3452 if (intf_id >= MAX_SUPPORTED_PON) {
3453 err = BCM_ERR_PARM;
3454 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pon intf_id - intf_id: %d, onu_id: %d\n",
3455 intf_id, onu_id);
3456 return bcm_to_grpc_err(err, "invalid pon intf_id");
3457 }
3458
3459 bcmolt_onu_rssi_measurement onu_oper; /* declare main API struct */
3460 bcmolt_onu_key onu_key; /**< Object key. */
3461 onu_rssi_compltd_key key(intf_id, onu_id);
3462 Queue<onu_rssi_complete_result> queue;
3463
3464 OPENOLT_LOG(INFO, openolt_log_id, "GetPonRxPower - intf_id %d, onu_id %d\n", intf_id, onu_id);
3465
3466 onu_key.onu_id = onu_id;
3467 onu_key.pon_ni = intf_id;
3468 /* Initialize the API struct. */
3469 BCMOLT_OPER_INIT(&onu_oper, onu, rssi_measurement, onu_key);
3470 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
3471 if (err == BCM_ERR_OK) {
3472 // initialize map
3473 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3474 onu_rssi_compltd_map.insert({key, &queue});
3475 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3476 } else {
3477 OPENOLT_LOG(ERROR, openolt_log_id, "failed to measure rssi rx power - intf_id: %d, onu_id: %d, err = %s (%d): %s\n",
3478 intf_id, onu_id, bcmos_strerror(err), err, onu_oper.hdr.hdr.err_text);
3479 return bcm_to_grpc_err(err, "failed to measure rssi rx power");
3480 }
3481
3482 onu_rssi_complete_result completed{};
3483 if (!queue.pop(completed, ONU_RSSI_COMPLETE_WAIT_TIMEOUT)) {
3484 // invalidate the queue pointer
3485 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3486 onu_rssi_compltd_map[key] = NULL;
3487 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3488 err = BCM_ERR_TIMEOUT;
3489 OPENOLT_LOG(ERROR, openolt_log_id, "timeout waiting for RSSI Measurement Completed indication intf_id %d, onu_id %d\n",
3490 intf_id, onu_id);
3491 } else {
3492 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",
3493 completed.pon_intf_id, completed.onu_id, completed.status.c_str(), completed.reason, completed.rx_power_mean_dbm);
3494
3495 response->set_intf_id(completed.pon_intf_id);
3496 response->set_onu_id(completed.onu_id);
3497 response->set_status(completed.status);
3498 response->set_fail_reason(static_cast<::openolt::PonRxPowerData_RssiMeasurementFailReason>(completed.reason));
3499 response->set_rx_power_mean_dbm(completed.rx_power_mean_dbm);
3500 }
3501
3502 // Remove entry from map
3503 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3504 onu_rssi_compltd_map.erase(key);
3505 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3506
3507 if (err == BCM_ERR_OK) {
3508 return Status::OK;
3509 } else {
3510 return bcm_to_grpc_err(err, "timeout waiting for pon rssi measurement complete indication");
3511 }
3512}