blob: 6252355d38da95b66719c5dfb215e059a8fb91e6 [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);
78
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000079inline const char *get_flow_acton_command(uint32_t command) {
80 char actions[200] = { };
81 char *s_actions_ptr = actions;
82 if (command & BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG) strcat(s_actions_ptr, "ADD_OUTER_TAG|");
83 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG) strcat(s_actions_ptr, "REMOVE_OUTER_TAG|");
84 if (command & BCMOLT_ACTION_CMD_ID_XLATE_OUTER_TAG) strcat(s_actions_ptr, "TRANSLATE_OUTER_TAG|");
85 if (command & BCMOLT_ACTION_CMD_ID_ADD_INNER_TAG) strcat(s_actions_ptr, "ADD_INNTER_TAG|");
86 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_INNER_TAG) strcat(s_actions_ptr, "REMOVE_INNER_TAG|");
87 if (command & BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG) strcat(s_actions_ptr, "TRANSLATE_INNER_TAG|");
88 if (command & BCMOLT_ACTION_CMD_ID_REMARK_OUTER_PBITS) strcat(s_actions_ptr, "REMOVE_OUTER_PBITS|");
89 if (command & BCMOLT_ACTION_CMD_ID_REMARK_INNER_PBITS) strcat(s_actions_ptr, "REMAKE_INNER_PBITS|");
90 return s_actions_ptr;
91}
92
kesavandc1f2db92020-08-31 15:32:06 +053093bcmolt_stat_alarm_config set_stat_alarm_config(const config::OnuItuPonAlarm* request) {
Jason Huang5d9ab1a2020-04-15 16:53:49 +080094 bcmolt_stat_alarm_config alarm_cfg = {};
95 bcmolt_stat_alarm_trigger_config trigger_obj = {};
96 bcmolt_stat_alarm_soak_config soak_obj = {};
97
98 switch (request->alarm_reporting_condition()) {
kesavandc1f2db92020-08-31 15:32:06 +053099 case config::OnuItuPonAlarm::RATE_THRESHOLD:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800100 trigger_obj.type = BCMOLT_STAT_CONDITION_TYPE_RATE_THRESHOLD;
101 BCMOLT_FIELD_SET(&trigger_obj.u.rate_threshold, stat_alarm_trigger_config_rate_threshold,
102 rising, request->rate_threshold_config().rate_threshold_rising());
103 BCMOLT_FIELD_SET(&trigger_obj.u.rate_threshold, stat_alarm_trigger_config_rate_threshold,
104 falling, request->rate_threshold_config().rate_threshold_falling());
105 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, active_soak_time,
106 request->rate_threshold_config().soak_time().active_soak_time());
107 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, clear_soak_time,
108 request->rate_threshold_config().soak_time().clear_soak_time());
109 break;
kesavandc1f2db92020-08-31 15:32:06 +0530110 case config::OnuItuPonAlarm::RATE_RANGE:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800111 trigger_obj.type = BCMOLT_STAT_CONDITION_TYPE_RATE_RANGE;
112 BCMOLT_FIELD_SET(&trigger_obj.u.rate_range, stat_alarm_trigger_config_rate_range, upper,
113 request->rate_range_config().rate_range_upper());
114 BCMOLT_FIELD_SET(&trigger_obj.u.rate_range, stat_alarm_trigger_config_rate_range, lower,
115 request->rate_range_config().rate_range_lower());
116 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, active_soak_time,
117 request->rate_range_config().soak_time().active_soak_time());
118 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, clear_soak_time,
119 request->rate_range_config().soak_time().clear_soak_time());
120 break;
kesavandc1f2db92020-08-31 15:32:06 +0530121 case config::OnuItuPonAlarm::VALUE_THRESHOLD:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800122 trigger_obj.type = BCMOLT_STAT_CONDITION_TYPE_VALUE_THRESHOLD;
123 BCMOLT_FIELD_SET(&trigger_obj.u.value_threshold, stat_alarm_trigger_config_value_threshold,
124 limit, request->value_threshold_config().threshold_limit());
125 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, active_soak_time,
126 request->value_threshold_config().soak_time().active_soak_time());
127 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, clear_soak_time,
128 request->value_threshold_config().soak_time().clear_soak_time());
129 break;
130 default:
131 OPENOLT_LOG(ERROR, openolt_log_id, "unsupported alarm reporting condition = %u\n", request->alarm_reporting_condition());
132 // For now just log the error and not return error. We can handle this scenario in the future.
133 break;
134 }
135
136 BCMOLT_FIELD_SET(&alarm_cfg, stat_alarm_config, trigger, trigger_obj);
137 BCMOLT_FIELD_SET(&alarm_cfg, stat_alarm_config, soak, soak_obj);
138
139 return alarm_cfg;
140}
141
kesavandc1f2db92020-08-31 15:32:06 +0530142Status OnuItuPonAlarmSet_(const config::OnuItuPonAlarm* request) {
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800143 bcmos_errno err;
144 bcmolt_onu_itu_pon_stats_cfg stat_cfg; /* declare main API struct */
145 bcmolt_onu_key key = {}; /* declare key */
146 bcmolt_stat_alarm_config errors_cfg = {};
147
148 key.pon_ni = request->pon_ni();
149 key.onu_id = request->onu_id();
150
151 /* Initialize the API struct. */
152 BCMOLT_STAT_CFG_INIT(&stat_cfg, onu, itu_pon_stats, key);
153
154 /*
155 1. BCMOLT_STAT_CONDITION_TYPE_NONE = 0, The alarm is disabled.
156 2. BCMOLT_STAT_CONDITION_TYPE_RATE_THRESHOLD = 1, The alarm is triggered if the stats delta value between samples
157 crosses the configured threshold boundary.
158 rising: The alarm is raised if the stats delta value per second becomes greater than this threshold level.
159 falling: The alarm is cleared if the stats delta value per second becomes less than this threshold level.
160 3. BCMOLT_STAT_CONDITION_TYPE_RATE_RANGE = 2, The alarm is triggered if the stats delta value between samples
161 deviates from the configured range.
162 upper: The alarm is raised if the stats delta value per second becomes greater than this upper level.
163 lower: The alarm is raised if the stats delta value per second becomes less than this lower level.
164 4. BCMOLT_STAT_CONDITION_TYPE_VALUE_THRESHOLD = 3, The alarm is raised if the stats sample value becomes greater
165 than this level. The alarm is cleared when the host read the stats.
166 limit: The alarm is raised if the stats sample value becomes greater than this level.
167 The alarm is cleared when the host clears the stats.
168
169 active_soak_time: If the alarm condition is raised and stays in the raised state for at least this amount
170 of time (unit=seconds), the alarm indication is sent to the host.
171 The OLT delays the alarm indication no less than this delay period.
172 It can be delayed more than this period because of the statistics sampling interval.
173 clear_soak_time: After the alarm is raised, if it is cleared and stays in the cleared state for at least
174 this amount of time (unit=seconds), the alarm indication is sent to the host.
175 The OLT delays the alarm indication no less than this delay period. It can be delayed more
176 than this period because of the statistics sampling interval.
177 */
178
179 errors_cfg = set_stat_alarm_config(request);
180
181 switch (request->alarm_id()) {
kesavandc1f2db92020-08-31 15:32:06 +0530182 case config::OnuItuPonAlarm_AlarmID::OnuItuPonAlarm_AlarmID_RDI_ERRORS:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800183 //set the rdi_errors alarm
184 BCMOLT_FIELD_SET(&stat_cfg.data, onu_itu_pon_stats_cfg_data, rdi_errors, errors_cfg);
185 break;
186 default:
187 OPENOLT_LOG(ERROR, openolt_log_id, "could not find the alarm id %d\n", request->alarm_id());
188 return bcm_to_grpc_err(BCM_ERR_PARM, "the alarm id is wrong");
189 }
190
191 err = bcmolt_stat_cfg_set(dev_id, &stat_cfg.hdr);
192 if (err != BCM_ERR_OK) {
193 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",
194 request->alarm_id(), key.pon_ni, key.onu_id, bcmos_strerror(err));
195 return bcm_to_grpc_err(err, "set Onu ITU PON stats alarm faild");
196 } else {
197 OPENOLT_LOG(INFO, openolt_log_id, "set onu itu pon stats alarm %d successfully, pon_ni %d, onu_id %d\n",
198 request->alarm_id(), key.pon_ni, key.onu_id);
199 }
200
201 return Status::OK;
202}
203
Girish Gowdra252f4972020-09-07 21:24:01 -0700204Status GetDeviceInfo_(::openolt::DeviceInfo* device_info) {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500205 device_info->set_vendor(VENDOR_ID);
206 device_info->set_model(MODEL_ID);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400207 device_info->set_hardware_version("");
208 device_info->set_firmware_version(firmware_version);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500209 device_info->set_technology(board_technology);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500210 device_info->set_pon_ports(num_of_pon_ports);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500211
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800212 char serial_number[OPENOLT_FIELD_LEN];
213 memset(serial_number, '\0', OPENOLT_FIELD_LEN);
214 openolt_read_sysinfo("Serial Number", serial_number);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000215 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device serial number %s\n", serial_number);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800216 device_info->set_device_serial_number(serial_number);
Burak Gurdag30db4822021-03-10 21:30:01 +0000217 device_info->set_previously_connected(state.previously_connected());
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800218
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700219 char device_id[OPENOLT_FIELD_LEN];
220 memset(device_id, '\0', OPENOLT_FIELD_LEN);
Humera Kouser6143c9e2020-06-17 22:37:31 +0530221
222 if (grpc_server_interface_name != NULL) {
223 if (get_intf_mac(grpc_server_interface_name, device_id, sizeof(device_id)) != NULL)
224 {
225 OPENOLT_LOG(INFO, openolt_log_id, "Fetched mac address %s of an interface %s\n", device_id, grpc_server_interface_name);
226 }
227 else
228 {
229 OPENOLT_LOG(ERROR, openolt_log_id, "Mac address of an interface %s is NULL\n", grpc_server_interface_name);
230 }
231 }
232 else
233 {
234 openolt_read_sysinfo("MAC", device_id);
235 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device mac address %s\n", device_id);
236 }
237
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700238 device_info->set_device_id(device_id);
239
Craig Lutgenb2601f02018-10-23 13:04:31 -0500240 // Legacy, device-wide ranges. To be deprecated when adapter
241 // is upgraded to support per-interface ranges
Girish Gowdra252f4972020-09-07 21:24:01 -0700242 device_info->set_onu_id_start(ONU_ID_START);
243 device_info->set_onu_id_end(ONU_ID_END);
244 device_info->set_alloc_id_start(ALLOC_ID_START);
245 device_info->set_alloc_id_end(ALLOC_ID_END);
246 device_info->set_gemport_id_start(GEM_PORT_ID_START);
247 device_info->set_gemport_id_end(GEM_PORT_ID_END);
248 device_info->set_flow_id_start(FLOW_ID_START);
249 device_info->set_flow_id_end(FLOW_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500250
Girish Gowdra252f4972020-09-07 21:24:01 -0700251 std::map<std::string, ::openolt::DeviceInfo::DeviceResourceRanges*> ranges;
Craig Lutgenb2601f02018-10-23 13:04:31 -0500252 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
253 std::string intf_technology = intf_technologies[intf_id];
Girish Gowdra252f4972020-09-07 21:24:01 -0700254 ::openolt::DeviceInfo::DeviceResourceRanges *range = ranges[intf_technology];
Craig Lutgenb2601f02018-10-23 13:04:31 -0500255 if(range == nullptr) {
256 range = device_info->add_ranges();
257 ranges[intf_technology] = range;
258 range->set_technology(intf_technology);
259
Girish Gowdra252f4972020-09-07 21:24:01 -0700260 ::openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
Craig Lutgenb2601f02018-10-23 13:04:31 -0500261
Girish Gowdra252f4972020-09-07 21:24:01 -0700262 pool = range->add_pools();
263 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
264 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
265 pool->set_start(ONU_ID_START);
266 pool->set_end(ONU_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500267
Girish Gowdra252f4972020-09-07 21:24:01 -0700268 pool = range->add_pools();
269 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
270 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
271 pool->set_start(ALLOC_ID_START);
272 pool->set_end(ALLOC_ID_START);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500273
Girish Gowdra252f4972020-09-07 21:24:01 -0700274 pool = range->add_pools();
275 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
276 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
277 pool->set_start(GEM_PORT_ID_START);
278 pool->set_end(GEM_PORT_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500279
Girish Gowdra252f4972020-09-07 21:24:01 -0700280 pool = range->add_pools();
281 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
282 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
283 pool->set_start(FLOW_ID_START);
284 pool->set_end(FLOW_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500285 }
286
287 range->add_intf_ids(intf_id);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500288 }
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400289
290 // FIXME: Once dependency problem is fixed
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500291 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400292 // device_info->set_onu_id_end(XGPON_NUM_OF_ONUS - 1);
293 // device_info->set_alloc_id_start(1024);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500294 // device_info->set_alloc_id_end(XGPON_NUM_OF_ALLOC_IDS * num_of_pon_ports ? - 1);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400295 // device_info->set_gemport_id_start(XGPON_MIN_BASE_SERVICE_PORT_ID);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500296 // device_info->set_gemport_id_end(XGPON_NUM_OF_GEM_PORT_IDS_PER_PON * num_of_pon_ports ? - 1);
297 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400298
299 return Status::OK;
300}
301
Thiyagarajan Subramani3e8bfd92021-04-26 15:07:14 +0530302void reset_pon_device(bcmolt_odid dev)
303{
304 bcmos_errno err;
305 bcmolt_device_reset oper;
306 bcmolt_device_key key = {.device_id = dev};
307
308 OPENOLT_LOG(INFO, openolt_log_id, "Reset PON device: %d\n", dev);
309
310 BCMOLT_OPER_INIT(&oper, device, reset, key);
311 err = bcmolt_oper_submit(dev_id, &oper.hdr);
312 if (err)
313 {
314 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to reset PON device(%d) failed, err = %s\n", dev, bcmos_strerror(err));
315 }else
316 {
317 OPENOLT_LOG(INFO, openolt_log_id, "Reset PON device(%d) success\n", dev);
318 }
319}
320
Shad Ansari627b5782018-08-13 22:49:32 +0000321Status Enable_(int argc, char *argv[]) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000322 bcmos_errno err;
323 bcmolt_host_init_parms init_parms = {};
324 init_parms.transport.type = BCM_HOST_API_CONN_LOCAL;
325 unsigned int failed_enable_device_cnt = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000326
Shad Ansariedef2132018-08-10 22:14:50 +0000327 if (!state.is_activated()) {
Shad Ansari627b5782018-08-13 22:49:32 +0000328
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500329 vendor_init();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000330 /* Initialize host subsystem */
331 err = bcmolt_host_init(&init_parms);
332 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500333 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to init OLT, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000334 return bcm_to_grpc_err(err, "Failed to init OLT");
335 }
336
337 bcmcli_session_parm mon_session_parm;
338 /* Create CLI session */
339 memset(&mon_session_parm, 0, sizeof(mon_session_parm));
340 mon_session_parm.get_prompt = openolt_cli_get_prompt_cb;
341 mon_session_parm.access_right = BCMCLI_ACCESS_ADMIN;
342 bcmos_errno rc = bcmcli_session_open(&mon_session_parm, &current_session);
343 BUG_ON(rc != BCM_ERR_OK);
344
345 /* API CLI */
346 bcm_openolt_api_cli_init(NULL, current_session);
347
348 /* Add quit command */
349 BCMCLI_MAKE_CMD_NOPARM(NULL, "quit", "Quit", bcm_cli_quit);
350
351 err = bcmolt_apiend_cli_init();
352 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500353 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to add apiend init, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000354 return bcm_to_grpc_err(err, "Failed to add apiend init");
355 }
356
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800357 bcmos_fastlock_init(&data_lock, 0);
Girish Gowdra252f4972020-09-07 21:24:01 -0700358 bcmos_fastlock_init(&acl_id_bitset_lock, 0);
359 bcmos_fastlock_init(&tm_sched_bitset_lock, 0);
360 bcmos_fastlock_init(&tm_qmp_bitset_lock, 0);
361 bcmos_fastlock_init(&flow_id_bitset_lock, 0);
362 bcmos_fastlock_init(&voltha_flow_to_device_flow_lock, 0);
Girish Gowdra96461052019-11-22 20:13:59 +0530363 bcmos_fastlock_init(&alloc_cfg_wait_lock, 0);
Girish Gowdra7a79dae2020-02-10 18:22:11 +0530364 bcmos_fastlock_init(&onu_deactivate_wait_lock, 0);
Girish Gowdra1935e6a2020-10-31 21:48:22 -0700365 bcmos_fastlock_init(&acl_packet_trap_handler_lock, 0);
366
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000367 OPENOLT_LOG(INFO, openolt_log_id, "Enable OLT - %s-%s\n", VENDOR_ID, MODEL_ID);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600368
Jason Huangbf45ffb2019-10-30 17:29:02 +0800369 //check BCM daemon is connected or not
370 Status status = check_connection();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000371 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800372 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000373 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800374 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000375 Status status = SubscribeIndication();
376 if (!status.ok()) {
377 OPENOLT_LOG(ERROR, openolt_log_id, "SubscribeIndication failed - %s : %s\n",
378 grpc_status_code_to_string(status.error_code()).c_str(),
379 status.error_message().c_str());
380 return status;
381 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800382
383 //check BAL state in initial stage
384 status = check_bal_ready();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000385 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800386 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000387 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800388 }
389
390 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000391 bcmos_errno err;
392 bcmolt_odid dev;
393 OPENOLT_LOG(INFO, openolt_log_id, "Enabling PON %d Devices ... \n", BCM_MAX_DEVS_PER_LINE_CARD);
394 for (dev = 0; dev < BCM_MAX_DEVS_PER_LINE_CARD; dev++) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400395 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000396 bcmolt_device_key dev_key = { };
397 dev_key.device_id = dev;
398 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
399 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
400 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
Jason Huangbf45ffb2019-10-30 17:29:02 +0800401 if (err == BCM_ERR_NOT_CONNECTED) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000402 bcmolt_device_key key = {.device_id = dev};
403 bcmolt_device_connect oper;
404 BCMOLT_OPER_INIT(&oper, device, connect, key);
Thiyagarajan Subramani3e8bfd92021-04-26 15:07:14 +0530405
406 /* BAL saves current state into dram_tune soc file and when dev_mgmt_daemon restarts
407 * it retains config from soc file. If openolt agent try to connect device without
408 * device reset device initialization fails hence doing device reset here. */
409 reset_pon_device(dev);
410
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000411 if (MODEL_ID == "asfvolt16") {
412 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
413 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_XGS__2_X);
414 } else if (MODEL_ID == "asgvolt64") {
415 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
416 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
417 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
Thiyagarajan Subramani3e8bfd92021-04-26 15:07:14 +0530418 } else if (MODEL_ID == "phoenix") {
419 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_NONE);
420 if(dev == 1) {
421 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
422 }
423 BCMOLT_MSG_FIELD_SET (&oper, ras_ddr_mode, BCMOLT_RAS_DDR_USAGE_MODE_TWO_DDRS);
424 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
425 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000426 }
427 err = bcmolt_oper_submit(dev_id, &oper.hdr);
428 if (err) {
429 failed_enable_device_cnt ++;
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500430 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 +0000431 if (failed_enable_device_cnt == BCM_MAX_DEVS_PER_LINE_CARD) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500432 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 +0000433 return Status(grpc::StatusCode::INTERNAL, "Failed to activate all PON ports");
434 }
435 }
436 bcmos_usleep(200000);
437 }
438 else {
439 OPENOLT_LOG(WARNING, openolt_log_id, "PON deivce %d already connected\n", dev);
440 state.activate();
441 }
442 }
443 init_stats();
Shad Ansari627b5782018-08-13 22:49:32 +0000444 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000445 }
Shad Ansariedef2132018-08-10 22:14:50 +0000446
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000447 /* Start CLI */
448 OPENOLT_LOG(INFO, def_log_id, "Starting CLI\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400449 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000450 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400451}
452
453Status Disable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400454 //In the earlier implementation Disabling olt is done by disabling the NNI port associated with that.
455 //In inband scenario instead of using management interface to establish connection with adapter ,NNI interface will be used.
456 //Disabling NNI port on olt disable causes connection loss between adapter and agent.
457 //To overcome this disable is implemented by disabling all the PON ports
458 //associated with the device so as to support both in-band
459 //and out of band scenarios.
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400460
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400461 Status status;
462 int failedCount = 0;
Girish Gowdrae1db2952021-05-04 00:16:54 -0700463 OPENOLT_LOG(INFO, openolt_log_id, "Received disable OLT\n");
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400464 for (int i = 0; i < NumPonIf_(); i++) {
465 status = DisablePonIf_(i);
466 if (!status.ok()) {
467 failedCount+=1;
468 BCM_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", i);
469 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400470 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400471 if (failedCount == 0) {
472 state.deactivate();
Girish Gowdra252f4972020-09-07 21:24:01 -0700473 ::openolt::Indication ind;
474 ::openolt::OltIndication* olt_ind = new ::openolt::OltIndication;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400475 olt_ind->set_oper_state("down");
476 ind.set_allocated_olt_ind(olt_ind);
477 BCM_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
478 oltIndQ.push(ind);
479 return Status::OK;
480 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000481 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400482 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to disable olt ,all the PON ports are still in enabled state");
483 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400484
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400485 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 -0400486}
487
488Status Reenable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400489 Status status;
490 int failedCount = 0;
491 for (int i = 0; i < NumPonIf_(); i++) {
492 status = EnablePonIf_(i);
493 if (!status.ok()) {
494 failedCount+=1;
495 BCM_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", i);
496 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400497 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000498 if (failedCount == 0) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400499 state.activate();
Girish Gowdra252f4972020-09-07 21:24:01 -0700500 ::openolt::Indication ind;
501 ::openolt::OltIndication* olt_ind = new ::openolt::OltIndication;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400502 olt_ind->set_oper_state("up");
503 ind.set_allocated_olt_ind(olt_ind);
504 BCM_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
505 oltIndQ.push(ind);
506 return Status::OK;
507 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000508 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400509 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to re-enable olt ,all the PON ports are still in disabled state");
510 }
511 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 +0000512}
513
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000514inline uint64_t get_flow_status(uint16_t flow_id, uint16_t flow_type, uint16_t data_id) {
515 bcmos_errno err;
516 bcmolt_flow_key flow_key;
517 bcmolt_flow_cfg flow_cfg;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400518
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000519 flow_key.flow_id = flow_id;
520 flow_key.flow_type = (bcmolt_flow_type)flow_type;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400521
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000522 BCMOLT_CFG_INIT(&flow_cfg, flow, flow_key);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400523
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000524 switch (data_id) {
525 case ONU_ID: //onu_id
526 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, onu_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500527 #ifdef TEST_MODE
528 // It is impossible to mock the setting of flow_cfg.data.state because
529 // the actual bcmolt_cfg_get passes the address of flow_cfg.hdr and we cannot
530 // set the flow_cfg.data. So a new stub function is created and address
531 // of flow_cfg is passed. This is one-of case where we need to add test specific
532 // code in production code.
533 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
534 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000535 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500536 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000537 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500538 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get onu_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000539 return err;
540 }
541 return flow_cfg.data.onu_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400542 case FLOW_TYPE:
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500543 #ifdef TEST_MODE
544 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
545 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000546 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500547 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000548 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500549 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get flow_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000550 return err;
551 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400552 return flow_cfg.key.flow_type;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000553 case SVC_PORT_ID: //svc_port_id
554 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, svc_port_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500555 #ifdef TEST_MODE
556 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
557 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000558 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500559 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000560 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500561 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get svc_port_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000562 return err;
563 }
564 return flow_cfg.data.svc_port_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400565 case PRIORITY:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000566 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, priority);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500567 #ifdef TEST_MODE
568 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
569 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000570 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500571 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000572 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500573 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get priority, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000574 return err;
575 }
576 return flow_cfg.data.priority;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400577 case COOKIE: //cookie
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000578 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, cookie);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500579 #ifdef TEST_MODE
580 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
581 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000582 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500583 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000584 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500585 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get cookie, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000586 return err;
587 }
588 return flow_cfg.data.cookie;
589 case INGRESS_INTF_TYPE: //ingress intf_type
590 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500591 #ifdef TEST_MODE
592 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
593 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000594 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500595 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000596 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500597 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get ingress intf_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000598 return err;
599 }
600 return flow_cfg.data.ingress_intf.intf_type;
601 case EGRESS_INTF_TYPE: //egress intf_type
602 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500603 #ifdef TEST_MODE
604 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
605 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000606 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500607 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000608 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500609 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress intf_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000610 return err;
611 }
612 return flow_cfg.data.egress_intf.intf_type;
613 case INGRESS_INTF_ID: //ingress intf_id
614 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500615 #ifdef TEST_MODE
616 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
617 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000618 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500619 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000620 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500621 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get ingress intf_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000622 return err;
623 }
624 return flow_cfg.data.ingress_intf.intf_id;
625 case EGRESS_INTF_ID: //egress intf_id
626 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500627 #ifdef TEST_MODE
628 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
629 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000630 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500631 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000632 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500633 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress intf_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000634 return err;
635 }
636 return flow_cfg.data.egress_intf.intf_id;
637 case CLASSIFIER_O_VID:
638 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500639 #ifdef TEST_MODE
640 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
641 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000642 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500643 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000644 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500645 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier o_vid, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000646 return err;
647 }
648 return flow_cfg.data.classifier.o_vid;
649 case CLASSIFIER_O_PBITS:
650 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500651 #ifdef TEST_MODE
652 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
653 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000654 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500655 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000656 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500657 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier o_pbits, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000658 return err;
659 }
660 return flow_cfg.data.classifier.o_pbits;
661 case CLASSIFIER_I_VID:
662 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500663 #ifdef TEST_MODE
664 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
665 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000666 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500667 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000668 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500669 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier i_vid, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000670 return err;
671 }
672 return flow_cfg.data.classifier.i_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400673 case CLASSIFIER_I_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000674 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500675 #ifdef TEST_MODE
676 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
677 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000678 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500679 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000680 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500681 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier i_pbits, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000682 return err;
683 }
684 return flow_cfg.data.classifier.i_pbits;
685 case CLASSIFIER_ETHER_TYPE:
686 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500687 #ifdef TEST_MODE
688 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
689 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000690 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500691 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000692 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500693 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier ether_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000694 return err;
695 }
696 return flow_cfg.data.classifier.ether_type;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400697 case CLASSIFIER_IP_PROTO:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000698 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500699 #ifdef TEST_MODE
700 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
701 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000702 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500703 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000704 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500705 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier ip_proto, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000706 return err;
707 }
708 return flow_cfg.data.classifier.ip_proto;
709 case CLASSIFIER_SRC_PORT:
710 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500711 #ifdef TEST_MODE
712 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
713 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000714 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500715 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000716 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500717 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier src_port, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000718 return err;
719 }
720 return flow_cfg.data.classifier.src_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400721 case CLASSIFIER_DST_PORT:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000722 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500723 #ifdef TEST_MODE
724 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
725 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000726 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500727 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000728 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500729 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier dst_port, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000730 return err;
731 }
732 return flow_cfg.data.classifier.dst_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400733 case CLASSIFIER_PKT_TAG_TYPE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000734 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500735 #ifdef TEST_MODE
736 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
737 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000738 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500739 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000740 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500741 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier pkt_tag_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000742 return err;
743 }
744 return flow_cfg.data.classifier.pkt_tag_type;
745 case EGRESS_QOS_TYPE:
746 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500747 #ifdef TEST_MODE
748 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
749 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000750 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500751 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000752 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500753 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000754 return err;
755 }
756 return flow_cfg.data.egress_qos.type;
757 case EGRESS_QOS_QUEUE_ID:
758 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500759 #ifdef TEST_MODE
760 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
761 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000762 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500763 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000764 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500765 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos queue_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000766 return err;
767 }
768 switch (flow_cfg.data.egress_qos.type) {
769 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE:
770 return flow_cfg.data.egress_qos.u.fixed_queue.queue_id;
771 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE:
772 return flow_cfg.data.egress_qos.u.tc_to_queue.tc_to_queue_id;
773 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC:
774 return flow_cfg.data.egress_qos.u.pbit_to_tc.tc_to_queue_id;
775 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE:
776 return flow_cfg.data.egress_qos.u.priority_to_queue.tm_q_set_id;
777 case BCMOLT_EGRESS_QOS_TYPE_NONE:
778 default:
779 return -1;
780 }
781 case EGRESS_QOS_TM_SCHED_ID:
782 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500783 #ifdef TEST_MODE
784 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
785 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000786 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500787 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000788 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500789 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos tm_sched_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000790 return err;
791 }
792 return flow_cfg.data.egress_qos.tm_sched.id;
793 case ACTION_CMDS_BITMASK:
794 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500795 #ifdef TEST_MODE
796 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
797 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000798 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500799 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000800 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500801 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action cmds_bitmask, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000802 return err;
803 }
804 return flow_cfg.data.action.cmds_bitmask;
805 case ACTION_O_VID:
806 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500807 #ifdef TEST_MODE
808 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
809 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000810 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500811 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000812 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500813 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action o_vid, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000814 return err;
815 }
816 return flow_cfg.data.action.o_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400817 case ACTION_O_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000818 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500819 #ifdef TEST_MODE
820 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
821 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000822 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500823 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000824 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500825 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action o_pbits, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000826 return err;
827 }
828 return flow_cfg.data.action.o_pbits;
829 case ACTION_I_VID:
830 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500831 #ifdef TEST_MODE
832 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
833 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000834 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500835 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000836 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500837 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action i_vid, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000838 return err;
839 }
840 return flow_cfg.data.action.i_vid;
841 case ACTION_I_PBITS:
842 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500843 #ifdef TEST_MODE
844 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
845 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000846 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500847 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000848 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500849 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action i_pbits, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000850 return err;
851 }
852 return flow_cfg.data.action.i_pbits;
853 case STATE:
854 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, state);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500855 #ifdef TEST_MODE
856 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
857 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000858 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500859 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000860 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500861 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get state, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000862 return err;
863 }
864 return flow_cfg.data.state;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000865 case GROUP_ID:
866 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, group_id);
867 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
868 if (err) {
869 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get group_id, err = %s\n",bcmos_strerror(err));
870 return err;
871 }
872 return flow_cfg.data.group_id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000873 default:
874 return BCM_ERR_INTERNAL;
875 }
876
877 return err;
878}
879
880Status EnablePonIf_(uint32_t intf_id) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400881 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000882 bcmolt_pon_interface_cfg interface_obj;
883 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
884 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
885 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530886 bcmolt_status los_status;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000887
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530888 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000889 if (err == BCM_ERR_OK) {
890 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800891 OPENOLT_LOG(WARNING, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000892 return Status::OK;
893 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400894 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000895 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
896 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
897 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
898 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.interval, 5000);
899 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.onu_post_discovery_mode,
Girish Gowdra24297032020-03-23 12:32:37 -0700900 BCMOLT_ONU_POST_DISCOVERY_MODE_NONE);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000901 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.los, true);
902 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.onu_alarms, true);
903 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.tiwi, true);
904 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.ack_timeout, true);
905 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.sfi, true);
906 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.loki, true);
Burak Gurdag5e587792020-05-06 14:58:02 +0000907
908 // On GPON, power level mode is not set to its default value (i.e. 0) as documented in Broadcom documentation.
909 // Instead, it is set to 2 which means -6 dbM attenuation. Therefore, we explicitly set it to the default value below.
910 if (board_technology == "GPON") {
911 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.pls_maximum_allocation_size, BCMOLT_PON_POWER_LEVEL_PLS_MAXIMUM_ALLOCATION_SIZE_DEFAULT);
912 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.mode, BCMOLT_PON_POWER_LEVEL_MODE_DEFAULT);
913 }
914
kesavandc1f2db92020-08-31 15:32:06 +0530915 //Enable AES Encryption
916 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.key_exchange, BCMOLT_CONTROL_STATE_ENABLE);
917 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.authentication, BCMOLT_CONTROL_STATE_ENABLE);
918 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.fail_due_to_authentication_failure, BCMOLT_CONTROL_STATE_ENABLE);
919
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000920 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
921 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
922
923 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
924 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500925 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 +0000926 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
927 }
928 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
929 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500930 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 +0000931 return bcm_to_grpc_err(err, "Failed to enable PON interface");
932 }
933 else {
934 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
935 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
936 CreateDefaultSched(intf_id, downstream);
937 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400938 }
939
940 return Status::OK;
941}
942
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500943Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000944 bcmos_errno err;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400945 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000946 bcmolt_device_key dev_key = { };
947 bcmolt_olt_cfg olt_cfg = { };
948 bcmolt_olt_key olt_key = { };
949 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
950 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500951
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000952 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
953 topo.topology_maps.arr = &topo_map[0];
954 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
955 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
956 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400957 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000958 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400959 #ifdef TEST_MODE
960 // It is impossible to mock the setting of olt_cfg.data.bal_state because
961 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
962 // set the olt_cfg.data.topology. So a new stub function is created and address
963 // of olt_cfg is passed. This is one-of case where we need to test add specific
964 // code in production code.
965 err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
966 #else
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000967 err = bcmolt_cfg_get_mult_retry(dev_id, &olt_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400968 #endif
969 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500970 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 +0000971 return bcm_to_grpc_err(err, "cfg: Failed to query OLT topology");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500972 }
973
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000974 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
975 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500976
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400977 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
978 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000979 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500980
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000981 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
982 num_of_nni_ports,
983 num_of_pon_ports,
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400984 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500985
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000986 uint32_t num_failed_cfg_gets = 0;
Jason Huang09b73ea2020-01-08 17:52:05 +0800987 static std::string openolt_version = firmware_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000988 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
989 dev_key.device_id = devid;
990 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
991 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
992 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
993 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000994 err = bcmolt_cfg_get_mult_retry(dev_id, &dev_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400995 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500996 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 +0000997 num_failed_cfg_gets++;
998 continue;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000999 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001000
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001001 std::string bal_version;
1002 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
1003 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
1004 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
Jason Huang09b73ea2020-01-08 17:52:05 +08001005 firmware_version = "BAL." + bal_version + "__" + openolt_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001006
1007 switch(dev_cfg.data.system_mode) {
1008 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
1009 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
1010 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
1011 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
1012 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
1013 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
1014 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
1015 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
1016 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
1017 case 20: board_technology = MIXED_TECH; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,MIXED_TECH); break;
1018 }
1019
1020 switch(dev_cfg.data.chip_family) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001021 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X: chip_family = "Maple"; break;
1022 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X: chip_family = "Aspen"; break;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001023 }
1024
Jason Huang09b73ea2020-01-08 17:52:05 +08001025 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s, family: %s, board_technology: %s\n",
1026 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 +00001027
1028 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001029 }
1030
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001031 /* 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 +00001032 only the devices that retured success*/
1033 if (num_failed_cfg_gets == BCM_MAX_DEVS_PER_LINE_CARD) {
1034 OPENOLT_LOG(ERROR, openolt_log_id, "device: Query of all the devices failed\n");
1035 return bcm_to_grpc_err(err, "device: All devices failed query");
1036 }
1037
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001038 return Status::OK;
1039}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001040
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001041Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001042 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001043 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
1044 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
1045 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001046
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001047 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001048 if (err == BCM_ERR_OK) {
1049 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001050 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001051 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1052 CreateDefaultSched(intf_id, upstream);
1053 CreateDefaultQueue(intf_id, upstream);
1054 return Status::OK;
1055 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1056 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
1057 return Status::OK;
1058 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001059 }
1060
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001061 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
1062 if (set_state) {
1063 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1064 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1065 } else {
1066 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1067 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1068 }
1069 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
1070 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001071 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err = %s\n",
1072 (set_state)?"enable":"disable", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001073 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
1074 }
1075 else {
1076 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
1077 if (set_state) {
1078 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1079 CreateDefaultSched(intf_id, upstream);
1080 CreateDefaultQueue(intf_id, upstream);
1081 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001082 }
1083
1084 return Status::OK;
1085}
1086
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001087Status DisablePonIf_(uint32_t intf_id) {
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001088 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001089 bcmolt_pon_interface_cfg interface_obj;
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001090 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1091 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001092
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001093 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
Girish Gowdrae1db2952021-05-04 00:16:54 -07001094 BCMOLT_MSG_FIELD_GET(&interface_obj, state);
1095
1096 err = bcmolt_cfg_get(dev_id, &interface_obj.hdr);
1097 if (err != BCM_ERR_OK) {
1098 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);
1099 return bcm_to_grpc_err(err, "Failed to fetch pon port state");
1100 }
1101 if (interface_obj.data.state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1102 OPENOLT_LOG(INFO, openolt_log_id, "PON Interface already inactive, PON interface %d\n", intf_id);
1103 return Status::OK;
1104 }
1105
1106 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001107 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1108 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_DISABLE);
1109
1110 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1111 if (err != BCM_ERR_OK) {
1112 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable discovery of onu, PON interface %d, err %d\n", intf_id, err);
1113 return bcm_to_grpc_err(err, "Failed to disable discovery of onu");
1114 }
1115
1116 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1117 operation, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1118
1119 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1120 if (err != BCM_ERR_OK) {
1121 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 -04001122 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001123 }
1124
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001125 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled PON interface: %d\n", intf_id);
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001126 return Status::OK;
1127}
1128
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001129Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
kesavandc1f2db92020-08-31 15:32:06 +05301130 const char *vendor_id, const char *vendor_specific, uint32_t pir, bool omcc_encryption_mode) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001131 bcmos_errno err = BCM_ERR_OK;
1132 bcmolt_onu_cfg onu_cfg;
1133 bcmolt_onu_key onu_key;
1134 bcmolt_serial_number serial_number; /**< ONU serial number */
1135 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001136
Girish Gowdra24297032020-03-23 12:32:37 -07001137 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1138 bcmolt_onu_state onu_state;
1139
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001140 onu_key.onu_id = onu_id;
1141 onu_key.pon_ni = intf_id;
1142 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1143 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Girish Gowdra24297032020-03-23 12:32:37 -07001144#ifdef TEST_MODE
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001145 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1146 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1147 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1148 // of onu_cfg is passed. This is one-of case where we need to add test specific
1149 // code in production code.
1150 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Girish Gowdra24297032020-03-23 12:32:37 -07001151#else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001152 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Girish Gowdra24297032020-03-23 12:32:37 -07001153#endif
1154 OPENOLT_LOG(INFO, openolt_log_id, "Activate ONU : old state = %d, current state = %d\n",
1155 onu_cfg.data.onu_old_state, onu_cfg.data.onu_state);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001156 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001157 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) {
1158 OPENOLT_LOG(INFO, openolt_log_id, "ONU is already in ACTIVE state, \
1159not processing this request for pon_intf=%d onu_id=%d\n", intf_id, onu_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001160 return Status::OK;
Girish Gowdra24297032020-03-23 12:32:37 -07001161 } else if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_NOT_CONFIGURED &&
1162 onu_cfg.data.onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1163 // We need the ONU to be in NOT_CONFIGURED or INACTIVE state to further process the request
1164 OPENOLT_LOG(ERROR, openolt_log_id, "ONU in an invalid state to process the request, \
1165state=%d pon_intf=%d onu_id=%d\n", onu_cfg.data.onu_state, intf_id, onu_id);
1166 return bcm_to_grpc_err(err, "Failed to activate ONU, invalid ONU state");
1167 }
1168 } else {
1169 // This should never happen. BAL GET should succeed for non-existant ONUs too. The state of such ONUs will be NOT_CONFIGURED
1170 OPENOLT_LOG(ERROR, openolt_log_id, "ONU state query failed pon_intf=%d onu_id=%d\n", intf_id, onu_id);
1171 return bcm_to_grpc_err(err, "onu get failed");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001172 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001173
Girish Gowdra24297032020-03-23 12:32:37 -07001174 // If the ONU is not configured at all we need to first configure it
1175 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_NOT_CONFIGURED) {
1176 OPENOLT_LOG(INFO, openolt_log_id, "Configuring ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001177vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Girish Gowdra24297032020-03-23 12:32:37 -07001178 vendor_specific_to_str(vendor_specific).c_str(), pir);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001179
Girish Gowdra24297032020-03-23 12:32:37 -07001180 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1181 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1182 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1183 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1184 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1185 /*set burst and data profiles to fec disabled*/
1186 if (board_technology == "XGS-PON") {
1187 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1188 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1189 } else if (board_technology == "GPON") {
1190 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1191 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1192 }
1193 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1194 if (err != BCM_ERR_OK) {
1195 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to configure ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
1196 return bcm_to_grpc_err(err, "Failed to configure ONU");
1197 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001198 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001199
Burak Gurdaga0523592021-02-24 15:17:47 +00001200// TODO: MOVE THIS TO A NEW METHOD
kesavandc1f2db92020-08-31 15:32:06 +05301201 if (omcc_encryption_mode == true) {
1202 // set the encryption mode for omci port id
1203 bcmolt_itupon_gem_cfg gem_cfg;
1204 bcmolt_itupon_gem_key key = {};
1205 bcmolt_gem_port_configuration configuration = {};
1206 key.pon_ni = intf_id;
1207 key.gem_port_id = onu_id;
1208 bcmolt_control_state encryption_mode;
1209 encryption_mode = BCMOLT_CONTROL_STATE_ENABLE;
1210 BCMOLT_CFG_INIT(&gem_cfg, itupon_gem, key);
1211 BCMOLT_FIELD_SET(&gem_cfg.data, itupon_gem_cfg_data, encryption_mode, encryption_mode);
1212 err = bcmolt_cfg_set(dev_id, &gem_cfg.hdr);
1213 if(err != BCM_ERR_OK) {
Burak Gurdaga0523592021-02-24 15:17:47 +00001214 OPENOLT_LOG(ERROR, openolt_log_id, "failed to configure omci gem_port encryption mode = %d\n", onu_id);
kesavandc1f2db92020-08-31 15:32:06 +05301215 return bcm_to_grpc_err(err, "Access_Control set ITU PON OMCI Gem port failed");
1216 }
1217 }
Girish Gowdra24297032020-03-23 12:32:37 -07001218 // Now that the ONU is configured, move the ONU to ACTIVE state
1219 memset(&onu_cfg, 0, sizeof(bcmolt_onu_cfg));
1220 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1221 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1222 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
1223 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
1224 onu_state, BCMOLT_ONU_OPERATION_ACTIVE);
1225 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001226 if (err != BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001227 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 +00001228 return bcm_to_grpc_err(err, "Failed to activate ONU");
1229 }
Girish Gowdra24297032020-03-23 12:32:37 -07001230 // ONU will eventually get activated after we have submitted the operation request. The adapter will receive an asynchronous
1231 // ONU_ACTIVATION_COMPLETED_INDICATION
1232
1233 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 +00001234
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001235 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001236}
1237
Jonathan Davis70c21812018-07-19 15:32:10 -04001238Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1239 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001240 bcmos_errno err = BCM_ERR_OK;
1241 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1242 bcmolt_onu_cfg onu_cfg;
1243 bcmolt_onu_key onu_key; /**< Object key. */
1244 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001245
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001246 onu_key.onu_id = onu_id;
1247 onu_key.pon_ni = intf_id;
1248 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1249 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001250 #ifdef TEST_MODE
1251 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1252 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1253 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1254 // of onu_cfg is passed. This is one-of case where we need to add test specific
1255 // code in production code.
1256 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001257 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001258 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001259 #endif
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301260 onu_state = onu_cfg.data.onu_state;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001261 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001262 switch (onu_state) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001263 case BCMOLT_ONU_STATE_ACTIVE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001264 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001265 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001266 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1267 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1268 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001269 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 +00001270 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1271 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301272 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 +00001273 break;
1274 }
Jonathan Davis70c21812018-07-19 15:32:10 -04001275 }
1276
1277 return Status::OK;
1278}
1279
1280Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001281 const char *vendor_id, const char *vendor_specific) {
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301282 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301283 bcmolt_onu_state onu_state;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001284
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001285 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 -05001286 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1287
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001288 // Need to deactivate before removing it (BAL rules)
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001289 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301290
1291 err = get_onu_status((bcmolt_interface)intf_id, onu_id, &onu_state);
1292 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001293 if (onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1294 OPENOLT_LOG(INFO, openolt_log_id, "waiting for onu deactivate complete response: intf_id=%d, onu_id=%d\n",
1295 intf_id, onu_id);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301296 err = wait_for_onu_deactivate_complete(intf_id, onu_id);
1297 if (err) {
1298 OPENOLT_LOG(ERROR, openolt_log_id, "failed to delete onu intf_id %d, onu_id %d\n",
1299 intf_id, onu_id);
1300 return bcm_to_grpc_err(err, "Failed to delete ONU");
1301 }
1302 }
Girish Gowdra24297032020-03-23 12:32:37 -07001303 else {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301304 OPENOLT_LOG(INFO, openolt_log_id, "Onu is Inactive, onu_id: %d, not waiting for onu deactivate complete response\n",
1305 intf_id);
1306 }
1307 }
1308 else {
1309 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch Onu status, onu_id = %d, intf_id = %d, err = %s\n",
1310 onu_id, intf_id, bcmos_strerror(err));
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301311 return bcm_to_grpc_err(err, "Failed to delete ONU");
1312 }
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001313
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001314 bcmolt_onu_cfg cfg_obj;
1315 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001316
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001317 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 -04001318 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001319
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001320 key.onu_id = onu_id;
1321 key.pon_ni = intf_id;
1322 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001323
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301324 err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001325 if (err != BCM_ERR_OK)
1326 {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001327 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to clear information for BAL onu_id %d, Interface ID %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
Jonathan Davis70c21812018-07-19 15:32:10 -04001328 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1329 }
1330
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301331 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 +00001332 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001333}
1334
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001335#define MAX_CHAR_LENGTH 20
1336#define MAX_OMCI_MSG_LENGTH 44
1337Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001338 bcmolt_bin_str buf = {};
1339 bcmolt_onu_cpu_packets omci_cpu_packets;
1340 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001341
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001342 key.pon_ni = intf_id;
1343 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001344
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001345 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1346 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1347 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001348
1349 // ???
1350 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1351 buf.len = MAX_OMCI_MSG_LENGTH;
1352 } else {
1353 buf.len = pkt.size()/2;
1354 }
1355
1356 /* Send the OMCI packet using the BAL remote proxy API */
1357 uint16_t idx1 = 0;
1358 uint16_t idx2 = 0;
1359 uint8_t arraySend[buf.len];
1360 char str1[MAX_CHAR_LENGTH];
1361 char str2[MAX_CHAR_LENGTH];
1362 memset(&arraySend, 0, buf.len);
1363
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001364 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1365 sprintf(str1,"%c", pkt[idx1]);
1366 sprintf(str2,"%c", pkt[++idx1]);
1367 strcat(str1,str2);
1368 arraySend[idx2] = strtol(str1, NULL, 16);
1369 }
1370
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001371 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1372 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001373
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001374 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1375 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1376 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001377
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001378 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001379 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001380 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 +00001381 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001382 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001383 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 -05001384 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001385 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001386 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001387
1388 return Status::OK;
1389}
1390
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001391Status 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 +00001392 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1393 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1394 bcmolt_bin_str buf = {};
1395 bcmolt_gem_port_id gem_port_id_array[1];
1396 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001397
Craig Lutgen967a1d02018-11-27 10:41:51 -06001398 if (port_no > 0) {
1399 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001400 if (gemport_id == 0) {
1401 bcmos_fastlock_lock(&data_lock);
1402 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1403 // Pick any flow that is mapped with the same port_no.
1404 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1405 if (it != port_to_flows.end() && !it->second.empty()) {
1406 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1407 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1408 if (fit != flowid_to_gemport.end()) {
1409 found = true;
1410 gemport_id = fit->second;
1411 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001412 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001413 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001414
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001415 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001416 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 -08001417 onu_id, port_no, intf_id);
1418 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1419 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001420 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 -08001421 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001422 }
1423
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001424 gem_port_id_array[0] = gemport_id;
1425 gem_port_list.len = 1;
1426 gem_port_list.arr = gem_port_id_array;
1427 buf.len = pkt.size();
1428 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1429 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1430
1431 /* init the API struct */
1432 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1433 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1434 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1435 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1436 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1437
1438 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1439 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1440
1441 /* call API */
1442 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001443 }
1444 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001445 //TODO: Port No is 0, it is coming sender requirement.
1446 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1447 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001448 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001449 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001450
1451 return Status::OK;
1452}
1453
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001454Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001455 bcmolt_flow_key key = {}; /* declare key */
1456 bcmolt_bin_str buffer = {};
1457 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001458
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001459 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
Girish Gowdra252f4972020-09-07 21:24:01 -07001460 bcmolt_flow_id flow_id = INVALID_FLOW_ID;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001461
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001462 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1463 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1464 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1465 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1466 key.flow_id = flow_id;
1467 else {
Jason Huang09b73ea2020-01-08 17:52:05 +08001468 if (flow_id_counters) {
1469 std::map<flow_pair, int>::iterator it;
1470 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1471 int flow_index = it->first.first;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001472 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1473 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1474 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1475 key.flow_id = flow_index;
1476 break;
1477 }
1478 }
1479 }
1480 else {
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001481 OPENOLT_LOG(ERROR, openolt_log_id, "no flow id found for uplink packetout\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001482 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1483 }
1484 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001485
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001486 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001487
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001488 /* Initialize the API struct. */
1489 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001490
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001491 buffer.len = pkt.size();
1492 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1493 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1494 if (buffer.arr == NULL) {
1495 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1496 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1497 }
1498 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1499
1500 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1501 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001502 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 -05001503 return bcm_to_grpc_err(BCM_ERR_SYSCALL_ERR, "Error sending packets via nni port");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001504 } else {
1505 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1506 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001507
1508 return Status::OK;
1509}
Girish Gowdra252f4972020-09-07 21:24:01 -07001510
Burak Gurdaga0523592021-02-24 15:17:47 +00001511bool get_aes_flag_for_gem_port(const google::protobuf::Map<unsigned int, bool> &gemport_to_aes, uint32_t gemport_id) {
1512 bool aes_flag = false;
1513 for (google::protobuf::Map<unsigned int, bool>::const_iterator it=gemport_to_aes.begin(); it!=gemport_to_aes.end(); it++) {
1514 if (it->first == gemport_id) {
1515 aes_flag = it->second;
1516 break;
1517 }
1518 }
1519 return aes_flag;
1520}
1521
Girish Gowdra252f4972020-09-07 21:24:01 -07001522Status FlowAddWrapper_(const ::openolt::Flow* request) {
1523
1524 int32_t access_intf_id = request->access_intf_id();
1525 int32_t onu_id = request->onu_id();
1526 int32_t uni_id = request->uni_id();
1527 uint32_t port_no = request->port_no();
1528 uint64_t voltha_flow_id = request->flow_id();
1529 uint64_t symmetric_voltha_flow_id = request->symmetric_flow_id();
1530 const std::string flow_type = request->flow_type();
1531 int32_t alloc_id = request->alloc_id();
1532 int32_t network_intf_id = request->network_intf_id();
1533 int32_t gemport_id = request->gemport_id();
1534 const ::openolt::Classifier& classifier = request->classifier();
1535 const ::openolt::Action& action = request->action();
1536 int32_t priority = request->priority();
1537 uint64_t cookie = request->cookie();
1538 int32_t group_id = request->group_id();
1539 uint32_t tech_profile_id = request->tech_profile_id();
1540 bool replicate_flow = request->replicate_flow();
1541 const google::protobuf::Map<unsigned int, unsigned int> &pbit_to_gemport = request->pbit_to_gemport();
Burak Gurdaga0523592021-02-24 15:17:47 +00001542 const google::protobuf::Map<unsigned int, bool> &gemport_to_aes = request->gemport_to_aes();
Girish Gowdra252f4972020-09-07 21:24:01 -07001543 uint16_t flow_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001544 bool enable_encryption;
Girish Gowdra252f4972020-09-07 21:24:01 -07001545
1546 // The intf_id variable defaults to access(PON) interface ID.
1547 // For trap-from-nni flow where access interface ID is not valid , change it to NNI interface ID
1548 // This intf_id identifies the pool from which we get the flow_id
1549 uint32_t intf_id = access_intf_id;
1550 if (onu_id < 1) {
1551 onu_id = 1;
1552 }
1553 if (access_intf_id < 0) {
1554 intf_id = network_intf_id;
1555 }
1556
1557 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)
1558 // This is the case of voltha_flow_id (not symmetric_voltha_flow_id)
1559 if (is_voltha_flow_installed(voltha_flow_id)) {
1560 OPENOLT_LOG(INFO, openolt_log_id, "voltha_flow_id=%lu, already installed\n", voltha_flow_id);
1561 return ::Status(grpc::StatusCode::ALREADY_EXISTS, "voltha-flow-already-installed");
1562 }
1563
Girish Gowdra252f4972020-09-07 21:24:01 -07001564 // This is the case of symmetric_voltha_flow_id
1565 // If symmetric_voltha_flow_id is available and valid in the Flow message,
1566 // check if it is installed, and use the corresponding device_flow_id
1567 if (symmetric_voltha_flow_id > 0 && is_voltha_flow_installed(symmetric_voltha_flow_id)) { // symmetric flow found
1568 OPENOLT_LOG(INFO, openolt_log_id, "symmetric flow and the symmetric flow is installed\n");
1569 const device_flow_params *dev_fl_symm_params;
1570 dev_fl_symm_params = get_device_flow_params(symmetric_voltha_flow_id);
1571 if (dev_fl_symm_params == NULL) {
1572 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)
1573 return ::Status(grpc::StatusCode::INTERNAL, "symmetric-flow-details-not-found");
1574 }
1575
1576 if (!replicate_flow) { // No flow replication
1577 flow_id = dev_fl_symm_params[0].flow_id;
1578 gemport_id = dev_fl_symm_params[0].gemport_id; // overwrite the gemport with symmetric flow gemport
1579 // Should be same as what is coming in this request.
Burak Gurdaga0523592021-02-24 15:17:47 +00001580 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001581 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1582 cl.set_o_pbits(dev_fl_symm_params[0].pbit);
1583 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1584 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001585 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001586 if (st.error_code() == grpc::StatusCode::OK) {
1587 device_flow dev_fl;
1588 dev_fl.is_flow_replicated = false;
1589 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1590 dev_fl.voltha_flow_id = voltha_flow_id;
1591 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params));
1592 // update voltha flow to cache
1593 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1594 }
1595 return st;
1596 } else { // Flow to be replicated
1597 OPENOLT_LOG(INFO, openolt_log_id,"symmetric flow and replication is needed\n");
1598 for (uint8_t i=0; i<NUMBER_OF_REPLICATED_FLOWS; i++) {
1599 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1600 flow_id = dev_fl_symm_params[i].flow_id;
1601 gemport_id = dev_fl_symm_params[i].gemport_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001602 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001603 cl.set_o_pbits(dev_fl_symm_params[i].pbit);
1604 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdrade65ab42020-12-17 23:08:43 -08001605 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001606 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001607 if (st.error_code() != grpc::StatusCode::OK && st.error_code() != grpc::StatusCode::ALREADY_EXISTS) {
1608 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);
1609 // On failure remove any successfully replicated flows installed so far for the voltha_flow_id
1610 if (i > 0) {
1611 for (int8_t j = i-1; j >= 0; j--) {
1612 flow_id = dev_fl_symm_params[j].flow_id;
1613 FlowRemove_(flow_id, flow_type);
1614 }
1615 }
1616 return st;
1617 }
1618 }
1619 device_flow dev_fl;
1620 dev_fl.is_flow_replicated = true;
1621 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1622 dev_fl.voltha_flow_id = voltha_flow_id;
1623 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params)*NUMBER_OF_REPLICATED_FLOWS);
1624 // update voltha flow to cache
1625 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1626 }
1627 } else { // No symmetric flow found
1628 if (!replicate_flow) { // No flow replication
1629 OPENOLT_LOG(INFO, openolt_log_id, "not a symmetric flow and replication is not needed\n");
1630 flow_id = get_flow_id();
1631 if (flow_id == INVALID_FLOW_ID) {
1632 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocated flow id for voltha-flow-id=%lu\n", voltha_flow_id);
1633 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1634 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001635 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001636 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1637 flow_type, alloc_id, network_intf_id, gemport_id, classifier,
Burak Gurdaga0523592021-02-24 15:17:47 +00001638 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001639 if (st.error_code() == grpc::StatusCode::OK) {
1640 device_flow dev_fl;
1641 dev_fl.is_flow_replicated = false;
1642 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // Invalid
1643 dev_fl.voltha_flow_id = voltha_flow_id;
1644 dev_fl.params[0].flow_id = flow_id;
1645 dev_fl.params[0].gemport_id = gemport_id;
1646 dev_fl.params[0].pbit = classifier.o_pbits();
1647 // update voltha flow to cache
1648 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1649 } else {
1650 // Free the flow id on failure
1651 free_flow_id(flow_id);
1652 }
1653 return st;
1654 } else { // Flow to be replicated
1655 OPENOLT_LOG(INFO, openolt_log_id,"not a symmetric flow and replication is needed\n");
1656 if (pbit_to_gemport.size() != NUMBER_OF_PBITS) {
1657 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pbit-to-gemport map size=%lu", pbit_to_gemport.size())
1658 return ::Status(grpc::StatusCode::OUT_OF_RANGE, "pbit-to-gemport-map-len-invalid-for-flow-replication");
1659 }
1660 uint16_t flow_ids[NUMBER_OF_REPLICATED_FLOWS];
1661 device_flow dev_fl;
1662 if (get_flow_ids(NUMBER_OF_REPLICATED_FLOWS, flow_ids)) {
1663 uint8_t cnt = 0;
1664 dev_fl.is_flow_replicated = true;
1665 dev_fl.voltha_flow_id = voltha_flow_id;
1666 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // invalid
1667 for (google::protobuf::Map<unsigned int, unsigned int>::const_iterator it=pbit_to_gemport.begin(); it!=pbit_to_gemport.end(); it++) {
1668 dev_fl.params[cnt].flow_id = flow_ids[cnt];
1669 dev_fl.params[cnt].pbit = it->first;
1670 dev_fl.params[cnt].gemport_id = it->second;
1671
1672 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1673 flow_id = dev_fl.params[cnt].flow_id;
1674 gemport_id = dev_fl.params[cnt].gemport_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001675 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001676 cl.set_o_pbits(dev_fl.params[cnt].pbit);
1677 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1678 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001679 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001680 if (st.error_code() != grpc::StatusCode::OK) {
1681 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);
1682 // Remove any successfully replicated flows installed so far for the voltha_flow_id
1683 if (cnt > 0) {
1684 for (int8_t j = cnt-1; j >= 0; j--) {
1685 flow_id = dev_fl.params[j].flow_id;
1686 FlowRemove_(flow_id, flow_type);
1687 }
1688 }
1689 // Free up all the flow IDs on failure
1690 free_flow_ids(NUMBER_OF_REPLICATED_FLOWS, flow_ids);
1691 return st;
1692 }
1693 cnt++;
1694 }
1695 // On successful flow replication update voltha-flow-id to device-flow map to cache
1696 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1697 } else {
1698 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocate flow ids for replication voltha-flow-id=%lu\n", voltha_flow_id);
1699 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1700 }
1701 }
1702 }
1703
1704 return Status::OK;
1705}
1706
1707
Craig Lutgen967a1d02018-11-27 10:41:51 -06001708Status 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 +00001709 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001710 int32_t alloc_id, int32_t network_intf_id,
1711 int32_t gemport_id, const ::openolt::Classifier& classifier,
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001712 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie,
Burak Gurdaga0523592021-02-24 15:17:47 +00001713 int32_t group_id, uint32_t tech_profile_id, bool aes_enabled) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001714 bcmolt_flow_cfg cfg;
1715 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001716 int32_t o_vid = -1;
1717 bool single_tag = false;
1718 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001719 bcmolt_classifier c_val = { };
1720 bcmolt_action a_val = { };
1721 bcmolt_tm_queue_ref tm_val = { };
1722 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05001723 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001724
Jason Huang09b73ea2020-01-08 17:52:05 +08001725 OPENOLT_LOG(INFO, openolt_log_id, "flow add received for flow_id=%u, flow_type=%s\n", flow_id, flow_type.c_str());
1726
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001727 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001728 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001729 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001730 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001731 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001732 } else if (flow_type.compare(multicast) == 0) {
1733 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001734 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001735 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001736 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001737 }
1738
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001739 BCMOLT_CFG_INIT(&cfg, flow, key);
1740 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001741
Jason Huang09b73ea2020-01-08 17:52:05 +08001742 if (action.cmd().trap_to_host()) {
Girish Gowdra1935e6a2020-10-31 21:48:22 -07001743 Status resp = handle_acl_rule_install(onu_id, flow_id, gemport_id, flow_type, access_intf_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001744 network_intf_id, classifier);
Jason Huang09b73ea2020-01-08 17:52:05 +08001745 return resp;
1746 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001747
1748 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1749
1750 if (access_intf_id >= 0 && network_intf_id >= 0) {
1751 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1752 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1753 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08001754 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1755 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001756 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1757 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1758 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1759 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1760 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001761 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001762 } else {
1763 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
1764 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001765 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001766
Burak Gurdaga0523592021-02-24 15:17:47 +00001767 if (onu_id >= ONU_ID_START) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001768 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
1769 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001770 if (gemport_id >= GEM_PORT_ID_START) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001771 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
1772 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001773 if (gemport_id >= GEM_PORT_ID_START && port_no != 0) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001774 bcmos_fastlock_lock(&data_lock);
1775 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
1776 port_to_flows[port_no].insert(key.flow_id);
1777 flowid_to_gemport[key.flow_id] = gemport_id;
1778 }
1779 else
1780 {
1781 flowid_to_port[key.flow_id] = port_no;
1782 }
1783 bcmos_fastlock_unlock(&data_lock, 0);
1784 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001785
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001786 if (priority_value >= 0) {
1787 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
1788 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301789
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001790 } else { // MULTICAST FLOW
1791 if (group_id >= 0) {
1792 BCMOLT_MSG_FIELD_SET(&cfg, group_id, group_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001793 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001794 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1795 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001796 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001797
1798 {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001799 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001800 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001801 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
1802 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001803 }
1804
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001805 if (classifier.dst_mac().size() > 0) {
1806 bcmos_mac_address d_mac = {};
1807 bcmos_mac_address_init(&d_mac);
1808 memcpy(d_mac.u8, classifier.dst_mac().data(), sizeof(d_mac.u8));
1809 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_mac %02x:%02x:%02x:%02x:%02x:%02x\n", d_mac.u8[0],
1810 d_mac.u8[1], d_mac.u8[2], d_mac.u8[3], d_mac.u8[4], d_mac.u8[5]);
1811 BCMOLT_FIELD_SET(&c_val, classifier, dst_mac, d_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001812 }
1813
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001814 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001815 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001816 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001817 }
1818 */
1819
1820 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001821 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
1822 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001823 }
1824
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001825 if (classifier.dst_ip()) {
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08001826 bcmos_ipv4_address d_ip = {};
1827 bcmos_ipv4_address_init(&d_ip);
1828 d_ip.u32 = classifier.dst_ip();
1829 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_ip %04x\n", d_ip.u32);
1830 BCMOLT_FIELD_SET(&c_val, classifier, dst_ip, d_ip);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001831 }
1832
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08001833 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001834 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001835 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001836 }
1837 */
1838
1839 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001840 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
1841 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001842 }
1843
1844 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001845 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
1846 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001847 }
1848
1849 if (!classifier.pkt_tag_type().empty()) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001850 if (classifier.o_vid()) {
1851 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
1852 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
1853 }
1854
1855 if (classifier.i_vid()) {
1856 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
1857 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
1858 }
1859
1860 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
1861 if (classifier.pkt_tag_type().compare("untagged") == 0) {
1862 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
1863 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
1864 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
1865 single_tag = true;
1866
1867 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301868 // OpenOlt adapter will send 0xFF in case of no pbit classification
1869 // If it is any other value (0 to 7), it is for outer pbit classification.
1870 // OpenFlow protocol does not provide inner pbit classification (in case of double tagged packets),
1871 // and VOLTHA has not used any workaround to solve this problem (for ex: use metadata field).
1872 // Also there exists no use case for i-pbit classification, so we can safely ignore this for now.
1873 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001874 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301875 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001876 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
1877 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001878
Jason Huang09b73ea2020-01-08 17:52:05 +08001879 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301880 // Same comments as in case of "single_tag" packets.
1881 // 0xFF means no pbit classification, otherwise a valid PCP (0 to 7).
1882 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001883 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301884 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001885 }
1886 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001887 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001888 }
1889
Jason Huang09b73ea2020-01-08 17:52:05 +08001890 const ::openolt::ActionCmd& cmd = action.cmd();
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001891
Jason Huang09b73ea2020-01-08 17:52:05 +08001892 if (cmd.add_outer_tag()) {
1893 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
1894 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001895 }
1896
Jason Huang09b73ea2020-01-08 17:52:05 +08001897 if (cmd.remove_outer_tag()) {
1898 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
1899 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
1900 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301901
Jason Huang09b73ea2020-01-08 17:52:05 +08001902 if (action.o_vid()) {
1903 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
1904 o_vid = action.o_vid();
1905 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
1906 }
1907
1908 if (action.o_pbits()) {
1909 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
1910 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
1911 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301912
Jason Huang09b73ea2020-01-08 17:52:05 +08001913 if (action.i_vid()) {
1914 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
1915 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
1916 }
1917
1918 if (action.i_pbits()) {
1919 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
1920 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
1921 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301922
Jason Huang09b73ea2020-01-08 17:52:05 +08001923 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
1924
Burak Gurdaga0523592021-02-24 15:17:47 +00001925 if ((access_intf_id >= 0) && (onu_id >= ONU_ID_START)) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001926 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
1927 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00001928 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 +00001929
Jason Huang09b73ea2020-01-08 17:52:05 +08001930 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1931 // Queue 0 on DS subscriber scheduler
1932 tm_val.queue_id = 0;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001933
Jason Huang09b73ea2020-01-08 17:52:05 +08001934 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1935 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1936 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001937
Jason Huang09b73ea2020-01-08 17:52:05 +08001938 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1939 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1940 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001941
Jason Huang09b73ea2020-01-08 17:52:05 +08001942 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1943 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
1944 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 +00001945
Jason Huang09b73ea2020-01-08 17:52:05 +08001946 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1947 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1948 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1949 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 +00001950
Jason Huang09b73ea2020-01-08 17:52:05 +08001951 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
1952 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1953 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1954 }
1955 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
1956 // NNI Scheduler ID
1957 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1958 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1959 // Queue 0 on NNI scheduler
1960 tm_val.queue_id = 0;
1961 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1962 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1963 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001964
Jason Huang09b73ea2020-01-08 17:52:05 +08001965 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 +00001966 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1967 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1968
Jason Huang09b73ea2020-01-08 17:52:05 +08001969 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1970 /* Fetch TM QMP ID mapped to US NNI scheduler */
1971 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
1972 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1973 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1974 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1975 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 +00001976
Jason Huang09b73ea2020-01-08 17:52:05 +08001977 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 +00001978 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1979 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001980 }
Shad Ansari39739bc2018-09-13 21:38:37 +00001981 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301982 } else {
1983 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1984 tm_val.queue_id = 0;
1985
1986 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
1987 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1988 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
1989
1990 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1991 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
1992 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00001993 }
1994
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001995 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001996
Girish Gowdra252f4972020-09-07 21:24:01 -07001997#ifndef SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001998 // BAL 3.1 supports statistics only for unicast flows.
1999 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
2000 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
2001 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002002#endif // SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002003
Girish Gowdra252f4972020-09-07 21:24:01 -07002004#ifndef SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002005#ifdef FLOW_CHECKER
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002006 //Flow Checker, To avoid duplicate flow.
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002007 if (flow_id_counters != 0) {
2008 bool b_duplicate_flow = false;
Jason Huang09b73ea2020-01-08 17:52:05 +08002009 std::map<flow_pair, int>::iterator it;
2010
2011 for(it = flow_map.begin(); it != flow_map.end(); it++) {
2012 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(it->first.first, it->first.second, ONU_ID)) && \
2013 (key.flow_type == it->first.second) && \
2014 (cfg.data.svc_port_id == get_flow_status(it->first.first, it->first.second, SVC_PORT_ID)) && \
2015 (cfg.data.priority == get_flow_status(it->first.first, it->first.second, PRIORITY)) && \
2016 (cfg.data.cookie == get_flow_status(it->first.first, it->first.second, COOKIE)) && \
2017 (cfg.data.ingress_intf.intf_type == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_TYPE)) && \
2018 (cfg.data.ingress_intf.intf_id == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_ID)) && \
2019 (cfg.data.egress_intf.intf_type == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_TYPE)) && \
2020 (cfg.data.egress_intf.intf_id == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_ID)) && \
2021 (c_val.o_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_VID)) && \
2022 (c_val.o_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_PBITS)) && \
2023 (c_val.i_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_VID)) && \
2024 (c_val.i_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_PBITS)) && \
2025 (c_val.ether_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_ETHER_TYPE)) && \
2026 (c_val.ip_proto == get_flow_status(it->first.first, it->first.second, CLASSIFIER_IP_PROTO)) && \
2027 (c_val.src_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_SRC_PORT)) && \
2028 (c_val.dst_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_DST_PORT)) && \
2029 (c_val.pkt_tag_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_PKT_TAG_TYPE)) && \
2030 (cfg.data.egress_qos.type == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TYPE)) && \
2031 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_QUEUE_ID)) && \
2032 (cfg.data.egress_qos.tm_sched.id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TM_SCHED_ID)) && \
2033 (a_val.cmds_bitmask == get_flow_status(it->first.first, it->first.second, ACTION_CMDS_BITMASK)) && \
2034 (a_val.o_vid == get_flow_status(it->first.first, it->first.second, ACTION_O_VID)) && \
2035 (a_val.i_vid == get_flow_status(it->first.first, it->first.second, ACTION_I_VID)) && \
2036 (a_val.o_pbits == get_flow_status(it->first.first, it->first.second, ACTION_O_PBITS)) && \
2037 (a_val.i_pbits == get_flow_status(it->first.first, it->first.second, ACTION_I_PBITS)) && \
2038 (cfg.data.state == get_flow_status(it->first.first, it->first.second, STATE)) && \
2039 (cfg.data.group_id == get_flow_status(it->first.first, it->first.second, GROUP_ID));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002040#ifdef SHOW_FLOW_PARAM
2041 // Flow Parameter
2042 FLOW_PARAM_LOG();
2043#endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002044 if (b_duplicate_flow) {
2045 FLOW_LOG(WARNING, "Flow duplicate", 0);
2046 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
2047 }
2048 }
2049 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002050#endif // FLOW_CHECKER
2051#endif // SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002052
2053 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2054 if (err) {
2055 FLOW_LOG(ERROR, "Flow add failed", err);
2056 return bcm_to_grpc_err(err, "flow add failed");
2057 } else {
2058 FLOW_LOG(INFO, "Flow add ok", err);
2059 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002060 flow_map[std::pair<int, int>(key.flow_id,key.flow_type)] = flow_map.size();
2061 flow_id_counters = flow_map.size();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002062 bcmos_fastlock_unlock(&data_lock, 0);
Girish Gowdra252f4972020-09-07 21:24:01 -07002063
2064 }
Burak Gurdaga0523592021-02-24 15:17:47 +00002065
2066 /*
2067 Enable AES encryption on GEM ports if they are used in downstream unicast flows.
2068 Rationale: We can't do upstream encryption in GPON. This change addresses the common denominator (and also minimum viable)
2069 use case for both technologies which is downstream unicast GEM port encryption. Since the downstream traffic is inherently
2070 broadcast to all the ONUs behind a PON port, encrypting the individual subscriber traffic in this direction is important
2071 and considered good enough in terms of security (See Section 12.1 of G.984.3). For upstream unicast and downstream multicast
2072 GEM encryption, we need to make additional changes specific to XGSPON. This will be done as a future work.
2073 */
2074 if (aes_enabled && (access_intf_id >= 0) && (gemport_id >= GEM_PORT_ID_START) && (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM)) {
2075 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);
2076 enable_encryption_for_gem_port(access_intf_id, gemport_id);
2077 } else {
2078 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);
2079 }
2080
Girish Gowdra252f4972020-09-07 21:24:01 -07002081 return Status::OK;
2082}
2083
2084Status FlowRemoveWrapper_(const ::openolt::Flow* request) {
2085 const std::string flow_type = request->flow_type();
2086 uint64_t voltha_flow_id = request->flow_id();
2087 Status st;
2088
2089 // If Voltha flow is not installed, return fail
2090 if (! is_voltha_flow_installed(voltha_flow_id)) {
2091 OPENOLT_LOG(ERROR, openolt_log_id, "voltha_flow_id=%lu not found\n", voltha_flow_id);
2092 return ::Status(grpc::StatusCode::NOT_FOUND, "voltha-flow-not-found");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002093 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04002094
Girish Gowdra252f4972020-09-07 21:24:01 -07002095 const device_flow *dev_fl = get_device_flow(voltha_flow_id);
2096 if (dev_fl == NULL) {
2097 OPENOLT_LOG(ERROR, openolt_log_id, "device flow for voltha_flow_id=%lu in the cache is NULL\n", voltha_flow_id);
2098 return ::Status(grpc::StatusCode::INTERNAL, "device-flow-null-in-cache");
2099 }
2100 if (dev_fl->is_flow_replicated) {
2101 // Note: Here we are ignoring FlowRemove failures
2102 for (int i=0; i<NUMBER_OF_REPLICATED_FLOWS; i++) {
2103 st = FlowRemove_(dev_fl->params[i].flow_id, flow_type);
2104 if (st.error_code() == grpc::StatusCode::OK) {
2105 free_flow_id(dev_fl->params[i].flow_id);
2106 }
2107 }
2108 } else {
2109 // Note: Here we are ignoring FlowRemove failures
2110 st = FlowRemove_(dev_fl->params[0].flow_id, flow_type);
2111 if (st.error_code() == grpc::StatusCode::OK) {
2112 free_flow_id(dev_fl->params[0].flow_id);
2113 }
2114 }
2115 // remove the flow from cache on voltha flow removal
2116 remove_voltha_flow_from_cache(voltha_flow_id);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002117 return Status::OK;
2118}
2119
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002120Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
2121
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002122 bcmolt_flow_cfg cfg;
2123 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002124
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002125 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002126 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002127 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002128 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002129 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002130 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002131 } else if(flow_type.compare(multicast) == 0) {
2132 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002133 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002134 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002135 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
2136 }
2137
Jason Huang09b73ea2020-01-08 17:52:05 +08002138 OPENOLT_LOG(INFO, openolt_log_id, "flow remove received for flow_id=%u, flow_type=%s\n",
2139 flow_id, flow_type.c_str());
2140
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002141 bcmos_fastlock_lock(&acl_packet_trap_handler_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002142 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
2143 int32_t gemport_id = -1;
2144 int32_t intf_id = -1;
2145 int16_t acl_id = -1;
2146 if (flow_to_acl_map.count(fl_id_fl_dir) > 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002147
2148 acl_id_intf_id ac_id_if_id = flow_to_acl_map[fl_id_fl_dir];
2149 acl_id = std::get<0>(ac_id_if_id);
2150 intf_id = std::get<1>(ac_id_if_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002151 // cleanup acl only if it is a valid acl. If not valid acl, it may be datapath flow.
2152 if (acl_id >= 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002153 Status resp = handle_acl_rule_cleanup(acl_id, intf_id, flow_type);
Jason Huang09b73ea2020-01-08 17:52:05 +08002154 if (resp.ok()) {
2155 OPENOLT_LOG(INFO, openolt_log_id, "acl removed ok for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2156 flow_to_acl_map.erase(fl_id_fl_dir);
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002157
2158 // 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
2159 if (trap_to_host_pkt_info_with_vlan_for_flow_id.count(flow_id) > 0) {
2160 trap_to_host_pkt_info_with_vlan pkt_info_with_vlan = trap_to_host_pkt_info_with_vlan_for_flow_id[flow_id];
2161 // Formulate the trap_to_host_pkt_info tuple key
2162 trap_to_host_pkt_info pkt_info(std::get<0>(pkt_info_with_vlan),
2163 std::get<1>(pkt_info_with_vlan),
2164 std::get<2>(pkt_info_with_vlan),
2165 std::get<3>(pkt_info_with_vlan));
2166 // Extract the value corresponding to trap_to_host_pkt_info key from trap_to_host_vlan_ids_for_trap_to_host_pkt_info
2167 // The value is a list of vlan_ids for the given trap_to_host_pkt_info key
2168 // Remove the vlan_id from the list that corresponded to the flow being removed.
2169 if (trap_to_host_vlan_ids_for_trap_to_host_pkt_info.count(pkt_info) > 0) {
2170 trap_to_host_vlan_ids_for_trap_to_host_pkt_info[pkt_info].remove(std::get<4>(pkt_info_with_vlan));
2171 } else {
2172 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",
2173 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));
2174 }
2175
2176 } else {
2177 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);
2178 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002179 } else {
2180 OPENOLT_LOG(ERROR, openolt_log_id, "acl remove error for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2181 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002182 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002183 return resp;
2184 }
2185 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002186 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002187
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002188 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002189 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002190 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002191 flowid_to_gemport.erase(key.flow_id);
2192 port_to_flows[port_no].erase(key.flow_id);
2193 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
2194 }
2195 else
2196 {
2197 flowid_to_port.erase(key.flow_id);
2198 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002199 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002200
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002201 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002202
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002203 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002204 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002205 OPENOLT_LOG(ERROR, openolt_log_id, "Error while removing %s flow, flow_id=%d, err = %s\n", flow_type.c_str(), flow_id, bcmos_strerror(err));
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002206 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
2207 }
2208
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002209 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002210 if (flow_id_counters != 0) {
2211 std::map<flow_pair, int>::iterator it;
2212 for(it = flow_map.begin(); it != flow_map.end(); it++) {
2213 if (it->first.first == flow_id && it->first.second == key.flow_type) {
2214 flow_id_counters -= 1;
2215 flow_map.erase(it);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002216 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002217 }
2218 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002219 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
2220
Jason Huang09b73ea2020-01-08 17:52:05 +08002221 flow_to_acl_map.erase(fl_id_fl_dir);
2222
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002223 bcmos_fastlock_unlock(&data_lock, 0);
2224
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002225 return Status::OK;
2226}
2227
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002228bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
2229 bcmos_errno err;
2230 bcmolt_tm_sched_cfg tm_sched_cfg;
2231 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2232 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
2233
Jason Huangbf45ffb2019-10-30 17:29:02 +08002234 //check TM scheduler has configured or not
2235 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2236 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002237 #ifdef TEST_MODE
2238 // It is impossible to mock the setting of tm_sched_cfg.data.state because
2239 // the actual bcmolt_cfg_get passes the address of tm_sched_cfg.hdr and we cannot
2240 // set the tm_sched_cfg.data.state. So a new stub function is created and address
2241 // of tm_sched_cfg is passed. This is one-of case where we need to add test specific
2242 // code in production code.
2243 err = bcmolt_cfg_get__tm_sched_stub(dev_id, &tm_sched_cfg);
2244 #else
Jason Huangbf45ffb2019-10-30 17:29:02 +08002245 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002246 #endif
Jason Huangbf45ffb2019-10-30 17:29:02 +08002247 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002248 OPENOLT_LOG(ERROR, openolt_log_id, "cfg: Failed to query TM scheduler, err = %s\n",bcmos_strerror(err));
Jason Huangbf45ffb2019-10-30 17:29:02 +08002249 return err;
2250 }
2251 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
2252 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
2253 return BCM_ERR_OK;
2254 }
2255
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002256 // bcmbal_tm_sched_owner
2257 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2258
2259 /**< The output of the tm_sched object instance */
2260 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
2261
2262 if (direction.compare(upstream) == 0) {
2263 // In upstream it is NNI scheduler
2264 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
2265 } else if (direction.compare(downstream) == 0) {
2266 // In downstream it is PON scheduler
2267 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2268 }
2269
2270 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2271
2272 // bcmbal_tm_sched_type
2273 // set the deafult policy to strict priority
2274 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2275
2276 // num_priorities: Max number of strict priority scheduling elements
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002277 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, NUM_OF_PRIORITIES);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002278
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002279 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2280 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002281 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
2282 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002283 return err;
2284 }
2285
2286 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2287 direction.c_str(), tm_sched_key.id, intf_id);
2288 return BCM_ERR_OK;
2289}
2290
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002291bcmos_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 -07002292 uint32_t alloc_id, ::tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
2293 ::tech_profile::SchedulingPolicy sched_policy, ::tech_profile::TrafficShapingInfo tf_sh_info,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002294 uint32_t tech_profile_id) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002295
2296 bcmos_errno err;
2297
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002298 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002299 bcmolt_tm_sched_cfg tm_sched_cfg;
2300 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002301 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 -04002302
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002303 // bcmbal_tm_sched_owner
2304 // In downstream it is sub_term scheduler
2305 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002306
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002307 /**< The output of the tm_sched object instance */
2308 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002309
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002310 // bcmbal_tm_sched_parent
2311 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2312 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
2313 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 +00002314 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002315 be achieved using the' virtual' type of attachment.
2316 tm_sched_owner.u.sub_term.intf_id = intf_id;
2317 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2318 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002319
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002320 // bcmbal_tm_sched_type
2321 // set the deafult policy to strict priority
2322 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002323
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002324 // num_priorities: Max number of strict priority scheduling elements
2325 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002326
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002327 // bcmbal_tm_shaping
2328 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2329 uint32_t cir = tf_sh_info.cir();
2330 uint32_t pir = tf_sh_info.pir();
2331 uint32_t burst = tf_sh_info.pbs();
2332 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2333 cir, pir, burst);
2334 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2335 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2336 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2337 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2338 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2339 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002340 }
2341
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002342 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002343 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002344 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002345intf_id %d, onu_id %d, uni_id %d, port_no %u, err = %s\n", tm_sched_key.id, intf_id, onu_id, uni_id, \
2346port_no, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002347 return err;
2348 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002349 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2350uni_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 -08002351
2352 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002353 bcmolt_itupon_alloc_cfg cfg;
2354 bcmolt_itupon_alloc_key key = { };
2355 key.pon_ni = intf_id;
2356 key.alloc_id = alloc_id;
2357 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
Burak Gurdag623fada2021-04-20 22:02:36 +00002358 /*
2359 PIR: Maximum Bandwidth
2360 CIR: Assured Bandwidth
2361 GIR: Fixed Bandwidth
2362 */
Burak Gurdag03919c72020-02-04 22:46:57 +00002363 int pir_bw = tf_sh_info.pir()*125; // conversion from kbps to bytes/sec
2364 int cir_bw = tf_sh_info.cir()*125; // conversion from kbps to bytes/sec
Burak Gurdag623fada2021-04-20 22:02:36 +00002365 int gir_bw = tf_sh_info.gir()*125; // conversion from kbps to bytes/sec
2366 int guaranteed_bw = cir_bw+gir_bw;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002367 //offset to match bandwidth granularity
2368 int offset_pir_bw = pir_bw%bw_granularity;
Burak Gurdag623fada2021-04-20 22:02:36 +00002369 int offset_gir_bw = gir_bw%bw_granularity;
2370 int offset_guaranteed_bw = guaranteed_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002371
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002372 pir_bw = pir_bw - offset_pir_bw;
Burak Gurdag623fada2021-04-20 22:02:36 +00002373 gir_bw = gir_bw - offset_gir_bw;
2374 guaranteed_bw = guaranteed_bw - offset_guaranteed_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002375
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002376 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002377
Burak Gurdag623fada2021-04-20 22:02:36 +00002378 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);
2379
2380 if (pir_bw == 0) {
2381 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be at least %d bytes/sec\n",
2382 (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2383 return BCM_ERR_PARM;
2384 } else if (pir_bw < guaranteed_bw) {
2385 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed bandwidth (%d)\n",
2386 pir_bw, guaranteed_bw);
2387 return BCM_ERR_PARM;
2388 }
2389
2390 // Setting additional bw eligibility and validating bw provisionings
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002391 switch (additional_bw) {
Burak Gurdag623fada2021-04-20 22:02:36 +00002392
2393 case tech_profile::AdditionalBW::AdditionalBW_BestEffort: //AdditionalBW_BestEffort - For T-Cont types 4 & 5
2394 if (pir_bw == guaranteed_bw) {
2395 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2396bandwidth for additional bandwidth eligibility of type Best Effort\n");
2397 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002398 }
2399 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2400 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002401
2402 case tech_profile::AdditionalBW::AdditionalBW_NA: //AdditionalBW_NA - For T-Cont types 3 & 5
2403 if (guaranteed_bw == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002404 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2405additional bandwidth eligibility of type Non-Assured (NA)\n");
2406 return BCM_ERR_PARM;
Burak Gurdag623fada2021-04-20 22:02:36 +00002407 } else if (pir_bw == guaranteed_bw) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002408 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
Burak Gurdag623fada2021-04-20 22:02:36 +00002409bandwidth for additional bandwidth eligibility of type Non-Assured\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002410 return BCM_ERR_PARM;
2411 }
2412 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2413 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002414
2415 case tech_profile::AdditionalBW::AdditionalBW_None: //AdditionalBW_None - For T-Cont types 1 & 2
2416 if (guaranteed_bw != pir_bw) {
2417 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be equal to maximum bandwidth \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002418for additional bandwidth eligibility of type None\n");
2419 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002420 }
2421 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2422 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002423
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002424 default:
Burak Gurdag623fada2021-04-20 22:02:36 +00002425 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid additional bandwidth eligibility value (%d) supplied.\n", additional_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002426 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002427 }
Burak Gurdag623fada2021-04-20 22:02:36 +00002428
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002429 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2430 in a fine granularity. */
2431 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
Burak Gurdag623fada2021-04-20 22:02:36 +00002432 /* Since we can assign minimum 64000 bytes/sec for cbr_rt_bw, we prefer assigning
2433 gir_bw to cbr_nrt_bw to allow smaller amounts.
2434 TODO: Specify CBR_RT_BW and CBR_NRT_BW separately from VOLTHA */
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002435 /* Fixed Bandwidth with no critical requirement of shaping */
Burak Gurdag623fada2021-04-20 22:02:36 +00002436 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, gir_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002437 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
Burak Gurdag623fada2021-04-20 22:02:36 +00002438 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, guaranteed_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002439 /* Maximum allocated bandwidth allowed for this alloc ID */
2440 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
Burak Gurdag623fada2021-04-20 22:02:36 +00002441
2442 if (pir_bw == gir_bw) { // T-Cont Type 1 --> set alloc type to NONE
2443 // the condition cir_bw == 0 is implicitly satistied
2444 OPENOLT_LOG(INFO, openolt_log_id, "Setting alloc type to NONE since maximum bandwidth is equal to fixed bandwidth\n");
2445 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NONE);
2446 } else { // For other T-Cont types, set alloc type to NSR. TODO: read the default from a config file.
2447 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
2448 }
2449
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002450 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002451 for skipped allocations during quiet window */
2452 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2453 /**< Allocation Profile index for CBR non-RT Bandwidth */
2454 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2455 /**< Allocation Profile index for CBR RT Bandwidth */
2456 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2457 /**< Alloc ID Weight used in case of Extended DBA mode */
2458 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2459 /**< Alloc ID Priority used in case of Extended DBA mode */
2460 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2461 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002462
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002463 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002464 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002465 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
Burak Gurdag623fada2021-04-20 22:02:36 +00002466port_no %u, alloc_id %d, err = %s (%s)\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err), cfg.hdr.hdr.err_text);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002467 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002468 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002469#ifndef SCALE_AND_PERF
Girish Gowdra96461052019-11-22 20:13:59 +05302470 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
2471 if (err) {
2472 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2473port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
2474 return err;
2475 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002476#endif
Girish Gowdra96461052019-11-22 20:13:59 +05302477
2478 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
2479port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
2480
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002481 }
2482
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002483 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002484}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002485
Girish Gowdra252f4972020-09-07 21:24:01 -07002486Status CreateTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002487 uint32_t intf_id = traffic_scheds->intf_id();
2488 uint32_t onu_id = traffic_scheds->onu_id();
2489 uint32_t uni_id = traffic_scheds->uni_id();
2490 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002491 std::string direction;
2492 unsigned int alloc_id;
Girish Gowdra252f4972020-09-07 21:24:01 -07002493 ::tech_profile::SchedulerConfig sched_config;
2494 ::tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002495 uint32_t priority;
2496 uint32_t weight;
Girish Gowdra252f4972020-09-07 21:24:01 -07002497 ::tech_profile::SchedulingPolicy sched_policy;
2498 ::tech_profile::TrafficShapingInfo traffic_shaping_info;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002499 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002500 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002501
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002502 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002503 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002504
2505 direction = GetDirection(traffic_sched.direction());
2506 if (direction.compare("direction-not-supported") == 0)
2507 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2508
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002509 alloc_id = traffic_sched.alloc_id();
2510 sched_config = traffic_sched.scheduler();
2511 additional_bw = sched_config.additional_bw();
2512 priority = sched_config.priority();
2513 weight = sched_config.weight();
2514 sched_policy = sched_config.sched_policy();
2515 traffic_shaping_info = traffic_sched.traffic_shaping_info();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002516 tech_profile_id = traffic_sched.tech_profile_id();
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002517 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002518 sched_policy, traffic_shaping_info, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002519 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002520 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002521 return bcm_to_grpc_err(err, "Failed to create scheduler");
2522 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002523 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002524 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002525}
Jonathan Davis70c21812018-07-19 15:32:10 -04002526
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002527bcmos_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 -04002528
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002529 bcmos_errno err;
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302530 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302531 bcmolt_status los_status;
Girish Gowdra96461052019-11-22 20:13:59 +05302532 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002533
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002534 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002535 bcmolt_itupon_alloc_cfg cfg;
2536 bcmolt_itupon_alloc_key key = { };
2537 key.pon_ni = intf_id;
2538 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302539 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002540
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002541 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002542 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2543 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002544 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2545 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002546 return err;
2547 }
Girish Gowdra96461052019-11-22 20:13:59 +05302548
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302549 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302550 if (err == BCM_ERR_OK) {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302551 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_OFF) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002552#ifndef SCALE_AND_PERF
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302553 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is enabled and LoS status is OFF, waiting for alloc cfg clear response\n",
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302554 intf_id);
2555 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2556 if (err) {
2557 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2558 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
2559 return err;
2560 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002561#endif
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302562 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302563 else if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_ON) {
2564 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is enabled but LoS status is ON, not waiting for alloc cfg clear response\n",
2565 intf_id);
2566 }
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302567 else if (state == BCMOLT_INTERFACE_STATE_INACTIVE) {
2568 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is disabled, not waiting for alloc cfg clear response\n",
2569 intf_id);
2570 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302571 } else {
2572 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch PON interface status, intf_id = %d, err = %s\n",
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302573 intf_id, bcmos_strerror(err));
Girish Gowdra96461052019-11-22 20:13:59 +05302574 return err;
2575 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002576 } else if (direction == downstream) {
2577 bcmolt_tm_sched_cfg cfg;
2578 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002579
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002580 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2581 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302582 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002583 } else {
2584 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2585 return BCM_ERR_OK;
2586 }
Girish Gowdra96461052019-11-22 20:13:59 +05302587
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002588 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2589 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2590 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002591 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002592intf_id %d, onu_id %d, tech_profile_id %d, err = %s\n", direction.c_str(), key.id, intf_id, onu_id, tech_profile_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002593 return err;
2594 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002595 }
2596
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002597 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d, tech_profile_id %d\n",
2598 direction.c_str(), sched_id, intf_id, onu_id, tech_profile_id);
2599 free_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002600 return BCM_ERR_OK;
2601}
2602
Girish Gowdra252f4972020-09-07 21:24:01 -07002603Status RemoveTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002604 uint32_t intf_id = traffic_scheds->intf_id();
2605 uint32_t onu_id = traffic_scheds->onu_id();
2606 uint32_t uni_id = traffic_scheds->uni_id();
2607 std::string direction;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002608 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002609 bcmos_errno err;
2610
2611 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002612 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002613
2614 direction = GetDirection(traffic_sched.direction());
2615 if (direction.compare("direction-not-supported") == 0)
2616 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2617
2618 int alloc_id = traffic_sched.alloc_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002619 int tech_profile_id = traffic_sched.tech_profile_id();
2620 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002621 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002622 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002623 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2624 }
2625 }
2626 return Status::OK;
2627}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002628
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002629bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2630 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002631 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002632 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2633 bcmolt_tm_qmp_key tm_qmp_key;
2634 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002635
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002636 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2637 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002638 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed tm queue mapping profile count is 16.\n");
2639 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002640 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002641
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002642 tm_qmp_key.id = tm_qmp_id;
2643 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2644 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2645 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002646
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002647 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2648 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2649 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002650 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2651 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002652
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002653 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002654 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002655 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2656 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002657 return err;
2658 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002659
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002660 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2661 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002662 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002663}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002664
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002665bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2666 bcmos_errno err;
2667 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2668 bcmolt_tm_qmp_key tm_qmp_key;
2669 tm_qmp_key.id = tm_qmp_id;
2670
2671 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2672 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2673 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002674 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2675 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002676 return err;
2677 }
2678
2679 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2680 tm_qmp_key.id);
2681 return BCM_ERR_OK;
2682}
2683
2684bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2685 bcmos_errno err;
2686
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002687 /* Create default queues on the given PON/NNI scheduler */
2688 for (int queue_id = 0; queue_id < NUMBER_OF_DEFAULT_INTERFACE_QUEUES; queue_id++) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002689 bcmolt_tm_queue_cfg tm_queue_cfg;
2690 bcmolt_tm_queue_key tm_queue_key = {};
2691 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2692 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002693 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2694 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2695 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002696
2697 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2698 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2699 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2700
2701 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2702 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002703 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", \
2704 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 +00002705 return err;
2706 }
2707
2708 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2709 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2710 }
2711 return BCM_ERR_OK;
2712}
2713
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002714bcmos_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 +00002715 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 +00002716 bcmos_errno err;
2717 bcmolt_tm_queue_cfg cfg;
2718 bcmolt_tm_queue_key key = { };
2719 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 +00002720gemport_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 +00002721
2722 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002723 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002724
2725 if (priority > 7) {
2726 return BCM_ERR_RANGE;
2727 }
2728
2729 /* FIXME: The upstream queues have to be created once only.
2730 The upstream queues on the NNI scheduler are shared by all subscribers.
2731 When the first scheduler comes in, the queues get created, and are re-used by all others.
2732 Also, these queues should be present until the last subscriber exits the system.
2733 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2734
2735 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2736 for each GEM in TECH PROFILE */
2737 key.id = queue_id_list[priority];
2738
2739 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2740 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2741 key.id = 0;
2742 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2743 }
2744 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2745 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2746 }
2747 else {
2748 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2749 }
2750
2751 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2752
2753 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2754 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
2755
2756 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2757 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002758 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002759sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, tech_profile_id %d, err = %s\n", \
2760 direction.c_str(), key.id, key.sched_id, key.tm_q_set_id, access_intf_id, onu_id, uni_id, tech_profile_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002761 return err;
2762 }
2763
Girish Gowdra252f4972020-09-07 21:24:01 -07002764 if (direction.compare(upstream) == 0) {
2765 Status st = install_gem_port(access_intf_id, onu_id, gemport_id);
2766 if (st.error_code() != grpc::StatusCode::ALREADY_EXISTS && st.error_code() != grpc::StatusCode::OK) {
2767 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);
2768 return BCM_ERR_INTERNAL;
2769 }
2770 }
2771
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002772 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 +00002773intf_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 +00002774 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002775}
2776
Girish Gowdra252f4972020-09-07 21:24:01 -07002777Status CreateTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002778 uint32_t intf_id = traffic_queues->intf_id();
2779 uint32_t onu_id = traffic_queues->onu_id();
2780 uint32_t uni_id = traffic_queues->uni_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002781 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002782 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002783 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002784 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002785 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 +00002786
2787 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2788 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2789 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2790 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002791 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002792
2793 direction = GetDirection(traffic_queue.direction());
2794 if (direction.compare("direction-not-supported") == 0)
2795 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2796
2797 queues_priority_q[i] = traffic_queue.priority();
2798 queues_pbit_map[i] = traffic_queue.pbit_map();
2799 }
2800
2801 std::vector<uint32_t> tmq_map_profile(8, 0);
2802 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2803 queues_priority_q, COUNT_OF(queues_priority_q));
2804 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002805 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002806
2807 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2808 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002809 err = CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2810 if (err != BCM_ERR_OK) {
2811 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2812 return bcm_to_grpc_err(err, "Failed to create tm queue mapping profile");
2813 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002814 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2815 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2816 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2817 }
2818 }
2819
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002820 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002821 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002822
2823 direction = GetDirection(traffic_queue.direction());
2824 if (direction.compare("direction-not-supported") == 0)
2825 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2826
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002827 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 +00002828
Girish Gowdruf26cf882019-05-01 23:47:58 -07002829 // If the queue exists already, lets not return failure and break the loop.
2830 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002831 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002832 return bcm_to_grpc_err(err, "Failed to create queue");
2833 }
2834 }
2835 return Status::OK;
2836}
2837
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002838bcmos_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 +00002839 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 +00002840 bcmolt_tm_queue_cfg cfg;
2841 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002842 bcmos_errno err;
2843
2844 if (direction == downstream) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002845 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2846 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 +00002847 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002848 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002849 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 -08002850 return BCM_ERR_OK;
2851 }
2852 } else {
Girish Gowdra4fd30672020-11-09 17:23:06 -08002853 // Gemports are bi-directional (except in multicast case). We create the gem port when we create the
2854 // upstream queue (see CreateQueue function) and it makes sense to delete them when remove the upstream queues.
2855 // For multicast case we do not manage the install/remove of gem port in agent application. It is managed by BAL.
2856 // Moreover it also makes sense to remove when upstream queue is getting removed because the upstream queue MUST exist always.
2857 // It is possible that the downstream queues are not created for a subscriber (for ex: upstream EAPoL trap flow only exists
2858 // but no other flow, and in this case only upstream scheduler and queues exist. We do not have a scenario where only downstream
2859 // subscriber flows exist but no upstream )
2860 remove_gem_port(access_intf_id, gemport_id);
2861
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002862 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2863 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002864 return BCM_ERR_OK;
2865 }
2866
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002867 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2868 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2869 // Reset the queue id to 0 when using fixed queue.
2870 key.id = 0;
2871 }
2872 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2873 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2874 }
2875 else {
2876 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2877 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002878
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002879 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2880 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002881 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002882 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, queue_id %d, sched_id %d, \
2883tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n",
2884 direction.c_str(), key.id, key.sched_id, key.tm_q_set_id, access_intf_id, onu_id, uni_id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002885 return err;
2886 }
2887
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002888 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2889intf_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 -08002890
2891 return BCM_ERR_OK;
2892}
2893
Girish Gowdra252f4972020-09-07 21:24:01 -07002894Status RemoveTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002895 uint32_t intf_id = traffic_queues->intf_id();
2896 uint32_t onu_id = traffic_queues->onu_id();
2897 uint32_t uni_id = traffic_queues->uni_id();
2898 uint32_t port_no = traffic_queues->port_no();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002899 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002900 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002901 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002902 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002903 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 +00002904
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002905 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002906 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002907
2908 direction = GetDirection(traffic_queue.direction());
2909 if (direction.compare("direction-not-supported") == 0)
2910 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2911
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002912 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 -08002913 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002914 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002915 return bcm_to_grpc_err(err, "Failed to remove queue");
2916 }
Jonathan Davis70c21812018-07-19 15:32:10 -04002917 }
2918
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002919 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE && (direction.compare(upstream) == 0 || direction.compare(downstream) == 0 && is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id))) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002920 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002921 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002922
2923 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
2924 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002925 err = RemoveTrafficQueueMappingProfile(tm_qmp_id);
2926 if (err != BCM_ERR_OK) {
2927 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2928 return bcm_to_grpc_err(err, "Failed to remove tm queue mapping profile");
2929 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002930 }
2931 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002932 clear_qos_type(intf_id, onu_id, uni_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04002933 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04002934}
Jason Huangbf45ffb2019-10-30 17:29:02 +08002935
Girish Gowdra252f4972020-09-07 21:24:01 -07002936Status PerformGroupOperation_(const ::openolt::Group *group_cfg) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002937
2938 bcmos_errno err;
2939 bcmolt_group_key key = {};
2940 bcmolt_group_cfg grp_cfg_obj;
2941 bcmolt_group_members_update grp_mem_upd;
2942 bcmolt_members_update_command grp_mem_upd_cmd;
2943 bcmolt_group_member_info member_info = {};
2944 bcmolt_group_member_info_list_u8 members = {};
2945 bcmolt_intf_ref interface_ref = {};
2946 bcmolt_egress_qos egress_qos = {};
2947 bcmolt_tm_sched_ref tm_sched_ref = {};
2948 bcmolt_action a_val = {};
2949
2950 uint32_t group_id = group_cfg->group_id();
2951
2952 OPENOLT_LOG(INFO, openolt_log_id, "PerformGroupOperation request received for Group %d\n", group_id);
2953
2954 if (group_id >= 0) {
2955 key.id = group_id;
2956 }
2957 else {
2958 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
2959 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
2960 }
2961
2962 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2963 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
2964
2965 OPENOLT_LOG(INFO, openolt_log_id, "Checking if Group %d exists...\n",group_id);
2966
2967 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
2968 if (err != BCM_ERR_OK) {
2969 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
2970 return bcm_to_grpc_err(err, "Error in querying group");
2971 }
2972
2973 members.len = group_cfg->members_size();
2974
2975 // IMPORTANT: A member cannot be added to a group if the group type is not determined.
2976 // Group type is determined after a flow is assigned to it.
2977 // Therefore, a group must be created first, then a flow (with multicast type) must be assigned to it.
2978 // Only then we can add members to the group.
2979
2980 // if group does not exist, create it and return.
2981 if (grp_cfg_obj.data.state == BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
2982
2983 if (members.len != 0) {
2984 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);
2985 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Non-empty member list given for non-existent group");
2986 } else {
2987
2988 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2989 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, cookie, key.id);
2990
2991 /* Setting group actions and action parameters, if any.
2992 Only remove_outer_tag and translate_inner_tag actions and i_vid action parameter
2993 are supported for multicast groups in BAL 3.1.
2994 */
2995 const ::openolt::Action& action = group_cfg->action();
2996 const ::openolt::ActionCmd &cmd = action.cmd();
2997
2998 bcmolt_action_cmd_id cmd_bmask = BCMOLT_ACTION_CMD_ID_NONE;
2999 if (cmd.remove_outer_tag()) {
3000 OPENOLT_LOG(INFO, openolt_log_id, "Action remove_outer_tag applied to Group %d.\n", group_id);
3001 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
3002 }
3003
3004 if (cmd.translate_inner_tag()) {
3005 OPENOLT_LOG(INFO, openolt_log_id, "Action translate_inner_tag applied to Group %d.\n", group_id);
3006 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG);
3007 }
3008
3009 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, cmd_bmask);
3010
3011 if (action.i_vid()) {
3012 OPENOLT_LOG(INFO, openolt_log_id, "Setting action parameter i_vid=%d for Group %d.\n", action.i_vid(), group_id);
3013 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
3014 }
3015
3016 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, action, a_val);
3017
3018 // Create group
3019 err = bcmolt_cfg_set(dev_id, &(grp_cfg_obj.hdr));
3020
3021 if (BCM_ERR_OK != err) {
3022 BCM_LOG(ERROR, openolt_log_id, "Failed to create Group %d, err = %s (%d)\n", key.id, bcmos_strerror(err), err);
3023 return bcm_to_grpc_err(err, "Error in creating group");
3024 }
3025
3026 BCM_LOG(INFO, openolt_log_id, "Group %d has been created and configured with empty member list.\n", key.id);
3027 return Status::OK;
3028 }
3029 }
3030
3031 // The group already exists. Continue configuring it according to the update member command.
3032
3033 OPENOLT_LOG(INFO, openolt_log_id, "Configuring existing Group %d.\n",group_id);
3034
3035 // MEMBER LIST CONSTRUCTION
3036 // Note that members.len can be 0 here. if the group already exists and the command is SET then sending
3037 // empty list to the group is a legit operation and this actually empties the member list.
3038 members.arr = (bcmolt_group_member_info*)bcmos_calloc((members.len)*sizeof(bcmolt_group_member_info));
3039
3040 if (!members.arr) {
3041 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to allocate memory for group member list.\n");
3042 return grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "Memory exhausted during member list creation");
3043 }
3044
3045 /* SET GROUP MEMBERS UPDATE COMMAND */
Girish Gowdra252f4972020-09-07 21:24:01 -07003046 ::openolt::Group::GroupMembersCommand command = group_cfg->command();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003047 switch(command) {
Girish Gowdra252f4972020-09-07 21:24:01 -07003048 case ::openolt::Group::SET_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003049 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_SET;
3050 OPENOLT_LOG(INFO, openolt_log_id, "Setting %d members for Group %d.\n", members.len, group_id);
3051 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003052 case ::openolt::Group::ADD_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003053 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_ADD;
3054 OPENOLT_LOG(INFO, openolt_log_id, "Adding %d members to Group %d.\n", members.len, group_id);
3055 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003056 case ::openolt::Group::REMOVE_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003057 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_REMOVE;
3058 OPENOLT_LOG(INFO, openolt_log_id, "Removing %d members from Group %d.\n", members.len, group_id);
3059 break;
3060 default :
3061 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid value %d for group member command.\n", command);
3062 bcmos_free(members.arr);
3063 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group member command");
3064 }
3065
3066 // SET MEMBERS LIST
3067 for (int i = 0; i < members.len; i++) {
3068
Girish Gowdra252f4972020-09-07 21:24:01 -07003069 if (command == ::openolt::Group::REMOVE_MEMBERS) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003070 OPENOLT_LOG(INFO, openolt_log_id, "Removing group member %d from group %d\n",i,key.id);
3071 } else {
3072 OPENOLT_LOG(INFO, openolt_log_id, "Adding group member %d to group %d\n",i,key.id);
3073 }
3074
Girish Gowdra252f4972020-09-07 21:24:01 -07003075 ::openolt::GroupMember *member = (::openolt::GroupMember *) &group_cfg->members()[i];
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003076
3077 // Set member interface type
Girish Gowdra252f4972020-09-07 21:24:01 -07003078 ::openolt::GroupMember::InterfaceType if_type = member->interface_type();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003079 switch(if_type){
Girish Gowdra252f4972020-09-07 21:24:01 -07003080 case ::openolt::GroupMember::PON :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003081 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_PON);
3082 OPENOLT_LOG(INFO, openolt_log_id, "Interface type PON is assigned to GroupMember %d\n",i);
3083 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003084 case ::openolt::GroupMember::EPON_1G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003085 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_1_G);
3086 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_1G is assigned to GroupMember %d\n",i);
3087 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003088 case ::openolt::GroupMember::EPON_10G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003089 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_10_G);
3090 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_10G is assigned to GroupMember %d\n",i);
3091 break;
3092 default :
3093 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid interface type value %d for GroupMember %d.\n",if_type,i);
3094 bcmos_free(members.arr);
3095 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface type for a group member");
3096 }
3097
3098 // Set member interface id
3099 if (member->interface_id() >= 0) {
3100 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_id, member->interface_id());
3101 OPENOLT_LOG(INFO, openolt_log_id, "Interface %d is assigned to GroupMember %d\n", member->interface_id(), i);
3102 } else {
3103 bcmos_free(members.arr);
3104 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface id for a group member");
3105 }
3106
3107 // Set member interface_ref
3108 BCMOLT_FIELD_SET(&member_info, group_member_info, intf, interface_ref);
3109
3110 // Set member gem_port_id. This must be a multicast gemport.
3111 if (member->gem_port_id() >= 0) {
3112 BCMOLT_FIELD_SET(&member_info, group_member_info, svc_port_id, member->gem_port_id());
3113 OPENOLT_LOG(INFO, openolt_log_id, "GEM Port %d is assigned to GroupMember %d\n", member->gem_port_id(), i);
3114 } else {
3115 bcmos_free(members.arr);
3116 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid gem port id for a group member");
3117 }
3118
3119 // Set member scheduler id and queue_id
3120 uint32_t tm_sched_id = get_default_tm_sched_id(member->interface_id(), downstream);
3121 OPENOLT_LOG(INFO, openolt_log_id, "Scheduler %d is assigned to GroupMember %d\n", tm_sched_id, i);
3122 BCMOLT_FIELD_SET(&tm_sched_ref, tm_sched_ref, id, tm_sched_id);
3123 BCMOLT_FIELD_SET(&egress_qos, egress_qos, tm_sched, tm_sched_ref);
3124
3125 // We assume that all multicast traffic destined to a PON port is using the same fixed queue.
3126 uint32_t tm_queue_id;
3127 if (member->priority() >= 0 && member->priority() < NUMBER_OF_DEFAULT_INTERFACE_QUEUES) {
3128 tm_queue_id = queue_id_list[member->priority()];
3129 OPENOLT_LOG(INFO, openolt_log_id, "Queue %d is assigned to GroupMember %d\n", tm_queue_id, i);
3130 BCMOLT_FIELD_SET(&egress_qos, egress_qos, type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
3131 BCMOLT_FIELD_SET(&egress_qos.u.fixed_queue, egress_qos_fixed_queue, queue_id, tm_queue_id);
3132 } else {
3133 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid fixed queue priority/ID %d for GroupMember %d\n", member->priority(), i);
3134 bcmos_free(members.arr);
3135 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid queue priority for a group member");
3136 }
3137
3138 BCMOLT_FIELD_SET(&member_info, group_member_info, egress_qos, egress_qos);
3139 BCMOLT_ARRAY_ELEM_SET(&(members), i, member_info);
3140 }
3141
3142 BCMOLT_OPER_INIT(&grp_mem_upd, group, members_update, key);
3143 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.members, members);
3144 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.command, grp_mem_upd_cmd);
3145
3146 err = bcmolt_oper_submit(dev_id, &(grp_mem_upd.hdr));
3147 bcmos_free(members.arr);
3148
3149 if (BCM_ERR_OK != err) {
3150 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);
3151 return bcm_to_grpc_err(err, "Failed to submit members update operation for the group");
3152 }
3153
3154 OPENOLT_LOG(INFO, openolt_log_id, "Successfully submitted members update operation for Group %d\n", key.id);
3155
3156 return Status::OK;
3157}
Burak Gurdageb4ca2e2020-06-15 07:48:26 +00003158
3159Status DeleteGroup_(uint32_t group_id) {
3160
3161 bcmos_errno err = BCM_ERR_OK;
3162 bcmolt_group_cfg grp_cfg_obj;
3163 bcmolt_group_key key = {};
3164
3165
3166 OPENOLT_LOG(INFO, openolt_log_id, "Delete request received for group %d\n", group_id);
3167
3168 if (group_id >= 0) {
3169 key.id = group_id;
3170 } else {
3171 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
3172 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
3173 }
3174
3175 /* init the BAL INIT API */
3176 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3177
3178 OPENOLT_LOG(DEBUG, openolt_log_id, "Checking if group %d exists...\n",group_id);
3179
3180 // CONFIGURE GROUP MEMBERS
3181 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
3182 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
3183
3184 if (err != BCM_ERR_OK) {
3185 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
3186 return bcm_to_grpc_err(err, "Error in querying group");
3187 }
3188
3189 if (grp_cfg_obj.data.state != BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
3190 OPENOLT_LOG(DEBUG, openolt_log_id, "Group %d exists. Will be deleted.\n",group_id);
3191 err = bcmolt_cfg_clear(dev_id, &(grp_cfg_obj.hdr));
3192 if (err != BCM_ERR_OK) {
3193 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d cannot be deleted err = %s (%d).\n", group_id, bcmos_strerror(err), err);
3194 return bcm_to_grpc_err(err, "Failed to delete group");;
3195 }
3196 } else {
3197 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d does not exist.\n", group_id);
3198 return Status(grpc::StatusCode::NOT_FOUND, "Group not found");
3199 }
3200
3201 OPENOLT_LOG(INFO, openolt_log_id, "Group %d has been deleted successfully.\n", group_id);
3202 return Status::OK;
Jason Huang1d9cfce2020-05-20 22:58:47 +08003203}
3204
Girish Gowdra252f4972020-09-07 21:24:01 -07003205Status GetLogicalOnuDistanceZero_(uint32_t intf_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003206 bcmos_errno err = BCM_ERR_OK;
3207 uint32_t mld = 0;
3208 double LD0;
3209
3210 err = getOnuMaxLogicalDistance(intf_id, &mld);
3211 if (err != BCM_ERR_OK) {
3212 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3213 }
3214
3215 LD0 = LOGICAL_DISTANCE(mld*1000, MINIMUM_ONU_RESPONSE_RANGING_TIME, ONU_BIT_TRANSMISSION_DELAY);
3216 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance zero is %f, (PON %d)\n", LD0, intf_id);
3217 response->set_intf_id(intf_id);
3218 response->set_logical_onu_distance_zero(LD0);
3219
3220 return Status::OK;
3221}
3222
Girish Gowdra252f4972020-09-07 21:24:01 -07003223Status GetLogicalOnuDistance_(uint32_t intf_id, uint32_t onu_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003224 bcmos_errno err = BCM_ERR_OK;
3225 bcmolt_itu_onu_params itu = {};
3226 bcmolt_onu_cfg onu_cfg;
3227 bcmolt_onu_key onu_key = {};
3228 uint32_t mld = 0;
3229 double LDi;
3230
3231 onu_key.pon_ni = intf_id;
3232 onu_key.onu_id = onu_id;
3233
3234 err = getOnuMaxLogicalDistance(intf_id, &mld);
3235 if (err != BCM_ERR_OK) {
3236 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3237 }
3238
3239 /* Initialize the API struct. */
3240 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
3241 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
3242 BCMOLT_FIELD_SET_PRESENT(&itu, itu_onu_params, ranging_time);
3243 BCMOLT_FIELD_SET(&onu_cfg.data, onu_cfg_data, itu, itu);
3244 #ifdef TEST_MODE
3245 // It is impossible to mock the setting of onu_cfg.data.onu_state because
3246 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
3247 // set the onu_cfg.data.onu_state. So a new stub function is created and address
3248 // of onu_cfg is passed. This is one-of case where we need to add test specific
3249 // code in production code.
3250 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
3251 #else
3252 /* Call API function. */
3253 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
3254 #endif
3255 if (err != BCM_ERR_OK) {
3256 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);
3257 return bcm_to_grpc_err(err, "Failed to retrieve ONU ranging time");
3258 }
3259
3260 if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_ACTIVE) {
3261 OPENOLT_LOG(ERROR, openolt_log_id, "ONU is not yet activated (PON %d, ONU id %d)\n", intf_id, onu_id);
3262 return bcm_to_grpc_err(BCM_ERR_PARM, "ONU is not yet activated\n");
3263 }
3264
3265 LDi = LOGICAL_DISTANCE(mld*1000, onu_cfg.data.itu.ranging_time, ONU_BIT_TRANSMISSION_DELAY);
3266 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance is %f, (PON %d, ONU id %d)\n", LDi, intf_id, onu_id);
3267 response->set_intf_id(intf_id);
3268 response->set_onu_id(onu_id);
3269 response->set_logical_onu_distance(LDi);
3270
3271 return Status::OK;
3272}
Burak Gurdag74e3ab82020-12-17 13:35:06 +00003273
3274Status GetOnuStatistics_(uint32_t intf_id, uint32_t onu_id, openolt::OnuStatistics* onu_stats) {
3275 bcmos_errno err;
3276
3277 err = get_onu_statistics((bcmolt_interface_id)intf_id, (bcmolt_onu_id)onu_id, onu_stats);
3278
3279 if (err != BCM_ERR_OK) {
3280 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));
3281 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of ONU statistics failed");
3282 }
3283
3284 OPENOLT_LOG(INFO, openolt_log_id, "retrieved ONU statistics for PON ID = %d, ONU ID = %d\n", (int)intf_id, (int)onu_id);
3285 return Status::OK;
3286}
3287
3288Status GetGemPortStatistics_(uint32_t intf_id, uint32_t gemport_id, openolt::GemPortStatistics* gemport_stats) {
3289 bcmos_errno err;
3290
3291 err = get_gemport_statistics((bcmolt_interface_id)intf_id, (bcmolt_gem_port_id)gemport_id, gemport_stats);
3292
3293 if (err != BCM_ERR_OK) {
3294 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));
3295 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of GEMPORT statistics failed");
3296 }
3297
3298 OPENOLT_LOG(INFO, openolt_log_id, "retrieved GEMPORT statistics for PON ID = %d, GEMPORT ID = %d\n", (int)intf_id, (int)gemport_id);
3299 return Status::OK;
3300}