blob: 3d8bd93a3811472aadae4a902a40916c9a13bab3 [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);
217
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700218 char device_id[OPENOLT_FIELD_LEN];
219 memset(device_id, '\0', OPENOLT_FIELD_LEN);
Humera Kouser6143c9e2020-06-17 22:37:31 +0530220
221 if (grpc_server_interface_name != NULL) {
222 if (get_intf_mac(grpc_server_interface_name, device_id, sizeof(device_id)) != NULL)
223 {
224 OPENOLT_LOG(INFO, openolt_log_id, "Fetched mac address %s of an interface %s\n", device_id, grpc_server_interface_name);
225 }
226 else
227 {
228 OPENOLT_LOG(ERROR, openolt_log_id, "Mac address of an interface %s is NULL\n", grpc_server_interface_name);
229 }
230 }
231 else
232 {
233 openolt_read_sysinfo("MAC", device_id);
234 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device mac address %s\n", device_id);
235 }
236
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700237 device_info->set_device_id(device_id);
238
Craig Lutgenb2601f02018-10-23 13:04:31 -0500239 // Legacy, device-wide ranges. To be deprecated when adapter
240 // is upgraded to support per-interface ranges
Girish Gowdra252f4972020-09-07 21:24:01 -0700241 device_info->set_onu_id_start(ONU_ID_START);
242 device_info->set_onu_id_end(ONU_ID_END);
243 device_info->set_alloc_id_start(ALLOC_ID_START);
244 device_info->set_alloc_id_end(ALLOC_ID_END);
245 device_info->set_gemport_id_start(GEM_PORT_ID_START);
246 device_info->set_gemport_id_end(GEM_PORT_ID_END);
247 device_info->set_flow_id_start(FLOW_ID_START);
248 device_info->set_flow_id_end(FLOW_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500249
Girish Gowdra252f4972020-09-07 21:24:01 -0700250 std::map<std::string, ::openolt::DeviceInfo::DeviceResourceRanges*> ranges;
Craig Lutgenb2601f02018-10-23 13:04:31 -0500251 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
252 std::string intf_technology = intf_technologies[intf_id];
Girish Gowdra252f4972020-09-07 21:24:01 -0700253 ::openolt::DeviceInfo::DeviceResourceRanges *range = ranges[intf_technology];
Craig Lutgenb2601f02018-10-23 13:04:31 -0500254 if(range == nullptr) {
255 range = device_info->add_ranges();
256 ranges[intf_technology] = range;
257 range->set_technology(intf_technology);
258
Girish Gowdra252f4972020-09-07 21:24:01 -0700259 ::openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
Craig Lutgenb2601f02018-10-23 13:04:31 -0500260
Girish Gowdra252f4972020-09-07 21:24:01 -0700261 pool = range->add_pools();
262 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
263 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
264 pool->set_start(ONU_ID_START);
265 pool->set_end(ONU_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500266
Girish Gowdra252f4972020-09-07 21:24:01 -0700267 pool = range->add_pools();
268 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
269 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
270 pool->set_start(ALLOC_ID_START);
271 pool->set_end(ALLOC_ID_START);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500272
Girish Gowdra252f4972020-09-07 21:24:01 -0700273 pool = range->add_pools();
274 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
275 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
276 pool->set_start(GEM_PORT_ID_START);
277 pool->set_end(GEM_PORT_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500278
Girish Gowdra252f4972020-09-07 21:24:01 -0700279 pool = range->add_pools();
280 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
281 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
282 pool->set_start(FLOW_ID_START);
283 pool->set_end(FLOW_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500284 }
285
286 range->add_intf_ids(intf_id);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500287 }
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400288
289 // FIXME: Once dependency problem is fixed
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500290 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400291 // device_info->set_onu_id_end(XGPON_NUM_OF_ONUS - 1);
292 // device_info->set_alloc_id_start(1024);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500293 // device_info->set_alloc_id_end(XGPON_NUM_OF_ALLOC_IDS * num_of_pon_ports ? - 1);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400294 // device_info->set_gemport_id_start(XGPON_MIN_BASE_SERVICE_PORT_ID);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500295 // device_info->set_gemport_id_end(XGPON_NUM_OF_GEM_PORT_IDS_PER_PON * num_of_pon_ports ? - 1);
296 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400297
298 return Status::OK;
299}
300
Shad Ansari627b5782018-08-13 22:49:32 +0000301Status Enable_(int argc, char *argv[]) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000302 bcmos_errno err;
303 bcmolt_host_init_parms init_parms = {};
304 init_parms.transport.type = BCM_HOST_API_CONN_LOCAL;
305 unsigned int failed_enable_device_cnt = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000306
Shad Ansariedef2132018-08-10 22:14:50 +0000307 if (!state.is_activated()) {
Shad Ansari627b5782018-08-13 22:49:32 +0000308
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500309 vendor_init();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000310 /* Initialize host subsystem */
311 err = bcmolt_host_init(&init_parms);
312 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500313 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to init OLT, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000314 return bcm_to_grpc_err(err, "Failed to init OLT");
315 }
316
317 bcmcli_session_parm mon_session_parm;
318 /* Create CLI session */
319 memset(&mon_session_parm, 0, sizeof(mon_session_parm));
320 mon_session_parm.get_prompt = openolt_cli_get_prompt_cb;
321 mon_session_parm.access_right = BCMCLI_ACCESS_ADMIN;
322 bcmos_errno rc = bcmcli_session_open(&mon_session_parm, &current_session);
323 BUG_ON(rc != BCM_ERR_OK);
324
325 /* API CLI */
326 bcm_openolt_api_cli_init(NULL, current_session);
327
328 /* Add quit command */
329 BCMCLI_MAKE_CMD_NOPARM(NULL, "quit", "Quit", bcm_cli_quit);
330
331 err = bcmolt_apiend_cli_init();
332 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500333 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to add apiend init, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000334 return bcm_to_grpc_err(err, "Failed to add apiend init");
335 }
336
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800337 bcmos_fastlock_init(&data_lock, 0);
Girish Gowdra252f4972020-09-07 21:24:01 -0700338 bcmos_fastlock_init(&acl_id_bitset_lock, 0);
339 bcmos_fastlock_init(&tm_sched_bitset_lock, 0);
340 bcmos_fastlock_init(&tm_qmp_bitset_lock, 0);
341 bcmos_fastlock_init(&flow_id_bitset_lock, 0);
342 bcmos_fastlock_init(&voltha_flow_to_device_flow_lock, 0);
Girish Gowdra96461052019-11-22 20:13:59 +0530343 bcmos_fastlock_init(&alloc_cfg_wait_lock, 0);
Girish Gowdra7a79dae2020-02-10 18:22:11 +0530344 bcmos_fastlock_init(&onu_deactivate_wait_lock, 0);
Girish Gowdra1935e6a2020-10-31 21:48:22 -0700345 bcmos_fastlock_init(&acl_packet_trap_handler_lock, 0);
346
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000347 OPENOLT_LOG(INFO, openolt_log_id, "Enable OLT - %s-%s\n", VENDOR_ID, MODEL_ID);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600348
Jason Huangbf45ffb2019-10-30 17:29:02 +0800349 //check BCM daemon is connected or not
350 Status status = check_connection();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000351 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800352 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000353 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800354 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000355 Status status = SubscribeIndication();
356 if (!status.ok()) {
357 OPENOLT_LOG(ERROR, openolt_log_id, "SubscribeIndication failed - %s : %s\n",
358 grpc_status_code_to_string(status.error_code()).c_str(),
359 status.error_message().c_str());
360 return status;
361 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800362
363 //check BAL state in initial stage
364 status = check_bal_ready();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000365 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800366 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000367 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800368 }
369
370 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000371 bcmos_errno err;
372 bcmolt_odid dev;
373 OPENOLT_LOG(INFO, openolt_log_id, "Enabling PON %d Devices ... \n", BCM_MAX_DEVS_PER_LINE_CARD);
374 for (dev = 0; dev < BCM_MAX_DEVS_PER_LINE_CARD; dev++) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400375 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000376 bcmolt_device_key dev_key = { };
377 dev_key.device_id = dev;
378 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
379 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
380 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
Jason Huangbf45ffb2019-10-30 17:29:02 +0800381 if (err == BCM_ERR_NOT_CONNECTED) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000382 bcmolt_device_key key = {.device_id = dev};
383 bcmolt_device_connect oper;
384 BCMOLT_OPER_INIT(&oper, device, connect, key);
385 if (MODEL_ID == "asfvolt16") {
386 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
387 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_XGS__2_X);
388 } else if (MODEL_ID == "asgvolt64") {
389 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
390 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
391 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
392 }
393 err = bcmolt_oper_submit(dev_id, &oper.hdr);
394 if (err) {
395 failed_enable_device_cnt ++;
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500396 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 +0000397 if (failed_enable_device_cnt == BCM_MAX_DEVS_PER_LINE_CARD) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500398 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 +0000399 return Status(grpc::StatusCode::INTERNAL, "Failed to activate all PON ports");
400 }
401 }
402 bcmos_usleep(200000);
403 }
404 else {
405 OPENOLT_LOG(WARNING, openolt_log_id, "PON deivce %d already connected\n", dev);
406 state.activate();
407 }
408 }
409 init_stats();
Shad Ansari627b5782018-08-13 22:49:32 +0000410 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000411 }
Shad Ansariedef2132018-08-10 22:14:50 +0000412
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000413 /* Start CLI */
414 OPENOLT_LOG(INFO, def_log_id, "Starting CLI\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400415 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000416 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400417}
418
419Status Disable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400420 //In the earlier implementation Disabling olt is done by disabling the NNI port associated with that.
421 //In inband scenario instead of using management interface to establish connection with adapter ,NNI interface will be used.
422 //Disabling NNI port on olt disable causes connection loss between adapter and agent.
423 //To overcome this disable is implemented by disabling all the PON ports
424 //associated with the device so as to support both in-band
425 //and out of band scenarios.
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400426
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400427 Status status;
428 int failedCount = 0;
429 for (int i = 0; i < NumPonIf_(); i++) {
430 status = DisablePonIf_(i);
431 if (!status.ok()) {
432 failedCount+=1;
433 BCM_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", i);
434 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400435 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400436 if (failedCount == 0) {
437 state.deactivate();
Girish Gowdra252f4972020-09-07 21:24:01 -0700438 ::openolt::Indication ind;
439 ::openolt::OltIndication* olt_ind = new ::openolt::OltIndication;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400440 olt_ind->set_oper_state("down");
441 ind.set_allocated_olt_ind(olt_ind);
442 BCM_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
443 oltIndQ.push(ind);
444 return Status::OK;
445 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000446 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400447 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to disable olt ,all the PON ports are still in enabled state");
448 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400449
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400450 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 -0400451}
452
453Status Reenable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400454 Status status;
455 int failedCount = 0;
456 for (int i = 0; i < NumPonIf_(); i++) {
457 status = EnablePonIf_(i);
458 if (!status.ok()) {
459 failedCount+=1;
460 BCM_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", i);
461 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400462 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000463 if (failedCount == 0) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400464 state.activate();
Girish Gowdra252f4972020-09-07 21:24:01 -0700465 ::openolt::Indication ind;
466 ::openolt::OltIndication* olt_ind = new ::openolt::OltIndication;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400467 olt_ind->set_oper_state("up");
468 ind.set_allocated_olt_ind(olt_ind);
469 BCM_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
470 oltIndQ.push(ind);
471 return Status::OK;
472 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000473 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400474 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to re-enable olt ,all the PON ports are still in disabled state");
475 }
476 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 +0000477}
478
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000479inline uint64_t get_flow_status(uint16_t flow_id, uint16_t flow_type, uint16_t data_id) {
480 bcmos_errno err;
481 bcmolt_flow_key flow_key;
482 bcmolt_flow_cfg flow_cfg;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400483
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000484 flow_key.flow_id = flow_id;
485 flow_key.flow_type = (bcmolt_flow_type)flow_type;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400486
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000487 BCMOLT_CFG_INIT(&flow_cfg, flow, flow_key);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400488
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000489 switch (data_id) {
490 case ONU_ID: //onu_id
491 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, onu_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500492 #ifdef TEST_MODE
493 // It is impossible to mock the setting of flow_cfg.data.state because
494 // the actual bcmolt_cfg_get passes the address of flow_cfg.hdr and we cannot
495 // set the flow_cfg.data. So a new stub function is created and address
496 // of flow_cfg is passed. This is one-of case where we need to add test specific
497 // code in production code.
498 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
499 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000500 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500501 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000502 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500503 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get onu_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000504 return err;
505 }
506 return flow_cfg.data.onu_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400507 case FLOW_TYPE:
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500508 #ifdef TEST_MODE
509 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
510 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000511 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500512 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000513 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500514 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get flow_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000515 return err;
516 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400517 return flow_cfg.key.flow_type;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000518 case SVC_PORT_ID: //svc_port_id
519 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, svc_port_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500520 #ifdef TEST_MODE
521 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
522 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000523 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500524 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000525 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500526 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 +0000527 return err;
528 }
529 return flow_cfg.data.svc_port_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400530 case PRIORITY:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000531 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, priority);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500532 #ifdef TEST_MODE
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 priority, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000539 return err;
540 }
541 return flow_cfg.data.priority;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400542 case COOKIE: //cookie
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000543 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, cookie);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500544 #ifdef TEST_MODE
545 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
546 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000547 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500548 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000549 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500550 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get cookie, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000551 return err;
552 }
553 return flow_cfg.data.cookie;
554 case INGRESS_INTF_TYPE: //ingress intf_type
555 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500556 #ifdef TEST_MODE
557 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
558 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000559 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500560 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000561 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500562 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 +0000563 return err;
564 }
565 return flow_cfg.data.ingress_intf.intf_type;
566 case EGRESS_INTF_TYPE: //egress intf_type
567 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500568 #ifdef TEST_MODE
569 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
570 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000571 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500572 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000573 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500574 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 +0000575 return err;
576 }
577 return flow_cfg.data.egress_intf.intf_type;
578 case INGRESS_INTF_ID: //ingress intf_id
579 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500580 #ifdef TEST_MODE
581 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
582 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000583 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500584 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000585 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500586 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 +0000587 return err;
588 }
589 return flow_cfg.data.ingress_intf.intf_id;
590 case EGRESS_INTF_ID: //egress intf_id
591 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500592 #ifdef TEST_MODE
593 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
594 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000595 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500596 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000597 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500598 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 +0000599 return err;
600 }
601 return flow_cfg.data.egress_intf.intf_id;
602 case CLASSIFIER_O_VID:
603 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500604 #ifdef TEST_MODE
605 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
606 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000607 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500608 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000609 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500610 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 +0000611 return err;
612 }
613 return flow_cfg.data.classifier.o_vid;
614 case CLASSIFIER_O_PBITS:
615 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500616 #ifdef TEST_MODE
617 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
618 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000619 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500620 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000621 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500622 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 +0000623 return err;
624 }
625 return flow_cfg.data.classifier.o_pbits;
626 case CLASSIFIER_I_VID:
627 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500628 #ifdef TEST_MODE
629 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
630 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000631 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500632 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000633 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500634 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 +0000635 return err;
636 }
637 return flow_cfg.data.classifier.i_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400638 case CLASSIFIER_I_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000639 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500640 #ifdef TEST_MODE
641 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
642 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000643 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500644 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000645 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500646 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 +0000647 return err;
648 }
649 return flow_cfg.data.classifier.i_pbits;
650 case CLASSIFIER_ETHER_TYPE:
651 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500652 #ifdef TEST_MODE
653 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
654 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000655 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500656 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000657 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500658 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 +0000659 return err;
660 }
661 return flow_cfg.data.classifier.ether_type;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400662 case CLASSIFIER_IP_PROTO:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000663 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500664 #ifdef TEST_MODE
665 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
666 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000667 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500668 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000669 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500670 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 +0000671 return err;
672 }
673 return flow_cfg.data.classifier.ip_proto;
674 case CLASSIFIER_SRC_PORT:
675 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500676 #ifdef TEST_MODE
677 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
678 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000679 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500680 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000681 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500682 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 +0000683 return err;
684 }
685 return flow_cfg.data.classifier.src_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400686 case CLASSIFIER_DST_PORT:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000687 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500688 #ifdef TEST_MODE
689 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
690 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000691 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500692 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000693 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500694 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 +0000695 return err;
696 }
697 return flow_cfg.data.classifier.dst_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400698 case CLASSIFIER_PKT_TAG_TYPE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000699 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500700 #ifdef TEST_MODE
701 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
702 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000703 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500704 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000705 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500706 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 +0000707 return err;
708 }
709 return flow_cfg.data.classifier.pkt_tag_type;
710 case EGRESS_QOS_TYPE:
711 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500712 #ifdef TEST_MODE
713 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
714 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000715 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500716 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000717 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500718 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 +0000719 return err;
720 }
721 return flow_cfg.data.egress_qos.type;
722 case EGRESS_QOS_QUEUE_ID:
723 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500724 #ifdef TEST_MODE
725 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
726 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000727 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500728 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000729 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500730 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 +0000731 return err;
732 }
733 switch (flow_cfg.data.egress_qos.type) {
734 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE:
735 return flow_cfg.data.egress_qos.u.fixed_queue.queue_id;
736 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE:
737 return flow_cfg.data.egress_qos.u.tc_to_queue.tc_to_queue_id;
738 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC:
739 return flow_cfg.data.egress_qos.u.pbit_to_tc.tc_to_queue_id;
740 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE:
741 return flow_cfg.data.egress_qos.u.priority_to_queue.tm_q_set_id;
742 case BCMOLT_EGRESS_QOS_TYPE_NONE:
743 default:
744 return -1;
745 }
746 case EGRESS_QOS_TM_SCHED_ID:
747 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500748 #ifdef TEST_MODE
749 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
750 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000751 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500752 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000753 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500754 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 +0000755 return err;
756 }
757 return flow_cfg.data.egress_qos.tm_sched.id;
758 case ACTION_CMDS_BITMASK:
759 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500760 #ifdef TEST_MODE
761 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
762 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000763 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500764 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000765 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500766 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 +0000767 return err;
768 }
769 return flow_cfg.data.action.cmds_bitmask;
770 case ACTION_O_VID:
771 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500772 #ifdef TEST_MODE
773 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
774 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000775 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500776 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000777 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500778 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 +0000779 return err;
780 }
781 return flow_cfg.data.action.o_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400782 case ACTION_O_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000783 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500784 #ifdef TEST_MODE
785 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
786 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000787 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500788 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000789 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500790 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 +0000791 return err;
792 }
793 return flow_cfg.data.action.o_pbits;
794 case ACTION_I_VID:
795 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500796 #ifdef TEST_MODE
797 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
798 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000799 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500800 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000801 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500802 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 +0000803 return err;
804 }
805 return flow_cfg.data.action.i_vid;
806 case ACTION_I_PBITS:
807 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500808 #ifdef TEST_MODE
809 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
810 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000811 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500812 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000813 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500814 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 +0000815 return err;
816 }
817 return flow_cfg.data.action.i_pbits;
818 case STATE:
819 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, state);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500820 #ifdef TEST_MODE
821 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
822 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000823 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500824 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000825 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500826 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get state, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000827 return err;
828 }
829 return flow_cfg.data.state;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000830 case GROUP_ID:
831 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, group_id);
832 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
833 if (err) {
834 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get group_id, err = %s\n",bcmos_strerror(err));
835 return err;
836 }
837 return flow_cfg.data.group_id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000838 default:
839 return BCM_ERR_INTERNAL;
840 }
841
842 return err;
843}
844
845Status EnablePonIf_(uint32_t intf_id) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400846 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000847 bcmolt_pon_interface_cfg interface_obj;
848 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
849 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
850 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530851 bcmolt_status los_status;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000852
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530853 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000854 if (err == BCM_ERR_OK) {
855 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800856 OPENOLT_LOG(WARNING, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000857 return Status::OK;
858 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400859 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000860 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
861 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
862 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
863 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.interval, 5000);
864 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.onu_post_discovery_mode,
Girish Gowdra24297032020-03-23 12:32:37 -0700865 BCMOLT_ONU_POST_DISCOVERY_MODE_NONE);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000866 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.los, true);
867 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.onu_alarms, true);
868 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.tiwi, true);
869 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.ack_timeout, true);
870 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.sfi, true);
871 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.loki, true);
Burak Gurdag5e587792020-05-06 14:58:02 +0000872
873 // On GPON, power level mode is not set to its default value (i.e. 0) as documented in Broadcom documentation.
874 // Instead, it is set to 2 which means -6 dbM attenuation. Therefore, we explicitly set it to the default value below.
875 if (board_technology == "GPON") {
876 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.pls_maximum_allocation_size, BCMOLT_PON_POWER_LEVEL_PLS_MAXIMUM_ALLOCATION_SIZE_DEFAULT);
877 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.mode, BCMOLT_PON_POWER_LEVEL_MODE_DEFAULT);
878 }
879
kesavandc1f2db92020-08-31 15:32:06 +0530880 //Enable AES Encryption
881 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.key_exchange, BCMOLT_CONTROL_STATE_ENABLE);
882 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.authentication, BCMOLT_CONTROL_STATE_ENABLE);
883 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.fail_due_to_authentication_failure, BCMOLT_CONTROL_STATE_ENABLE);
884
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000885 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
886 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
887
888 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
889 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500890 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 +0000891 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
892 }
893 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
894 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500895 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 +0000896 return bcm_to_grpc_err(err, "Failed to enable PON interface");
897 }
898 else {
899 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
900 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
901 CreateDefaultSched(intf_id, downstream);
902 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400903 }
904
905 return Status::OK;
906}
907
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500908Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000909 bcmos_errno err;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400910 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000911 bcmolt_device_key dev_key = { };
912 bcmolt_olt_cfg olt_cfg = { };
913 bcmolt_olt_key olt_key = { };
914 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
915 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500916
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000917 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
918 topo.topology_maps.arr = &topo_map[0];
919 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
920 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
921 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400922 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000923 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400924 #ifdef TEST_MODE
925 // It is impossible to mock the setting of olt_cfg.data.bal_state because
926 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
927 // set the olt_cfg.data.topology. So a new stub function is created and address
928 // of olt_cfg is passed. This is one-of case where we need to test add specific
929 // code in production code.
930 err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
931 #else
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000932 err = bcmolt_cfg_get_mult_retry(dev_id, &olt_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400933 #endif
934 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500935 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 +0000936 return bcm_to_grpc_err(err, "cfg: Failed to query OLT topology");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500937 }
938
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000939 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
940 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500941
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400942 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
943 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000944 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500945
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000946 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
947 num_of_nni_ports,
948 num_of_pon_ports,
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400949 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500950
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000951 uint32_t num_failed_cfg_gets = 0;
Jason Huang09b73ea2020-01-08 17:52:05 +0800952 static std::string openolt_version = firmware_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000953 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
954 dev_key.device_id = devid;
955 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
956 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
957 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
958 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000959 err = bcmolt_cfg_get_mult_retry(dev_id, &dev_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400960 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500961 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 +0000962 num_failed_cfg_gets++;
963 continue;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000964 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500965
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000966 std::string bal_version;
967 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
968 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
969 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
Jason Huang09b73ea2020-01-08 17:52:05 +0800970 firmware_version = "BAL." + bal_version + "__" + openolt_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000971
972 switch(dev_cfg.data.system_mode) {
973 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
974 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
975 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
976 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
977 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
978 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
979 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
980 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
981 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
982 case 20: board_technology = MIXED_TECH; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,MIXED_TECH); break;
983 }
984
985 switch(dev_cfg.data.chip_family) {
Jason Huang09b73ea2020-01-08 17:52:05 +0800986 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X: chip_family = "Maple"; break;
987 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X: chip_family = "Aspen"; break;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000988 }
989
Jason Huang09b73ea2020-01-08 17:52:05 +0800990 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s, family: %s, board_technology: %s\n",
991 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 +0000992
993 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500994 }
995
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000996 /* 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 +0000997 only the devices that retured success*/
998 if (num_failed_cfg_gets == BCM_MAX_DEVS_PER_LINE_CARD) {
999 OPENOLT_LOG(ERROR, openolt_log_id, "device: Query of all the devices failed\n");
1000 return bcm_to_grpc_err(err, "device: All devices failed query");
1001 }
1002
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001003 return Status::OK;
1004}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001005
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001006Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001007 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001008 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
1009 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
1010 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001011
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001012 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001013 if (err == BCM_ERR_OK) {
1014 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001015 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001016 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1017 CreateDefaultSched(intf_id, upstream);
1018 CreateDefaultQueue(intf_id, upstream);
1019 return Status::OK;
1020 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1021 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
1022 return Status::OK;
1023 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001024 }
1025
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001026 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
1027 if (set_state) {
1028 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1029 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1030 } else {
1031 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1032 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1033 }
1034 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
1035 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001036 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err = %s\n",
1037 (set_state)?"enable":"disable", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001038 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
1039 }
1040 else {
1041 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
1042 if (set_state) {
1043 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1044 CreateDefaultSched(intf_id, upstream);
1045 CreateDefaultQueue(intf_id, upstream);
1046 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001047 }
1048
1049 return Status::OK;
1050}
1051
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001052Status DisablePonIf_(uint32_t intf_id) {
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001053 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001054 bcmolt_pon_interface_cfg interface_obj;
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001055 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1056 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001057
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001058 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
1059 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1060 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_DISABLE);
1061
1062 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1063 if (err != BCM_ERR_OK) {
1064 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable discovery of onu, PON interface %d, err %d\n", intf_id, err);
1065 return bcm_to_grpc_err(err, "Failed to disable discovery of onu");
1066 }
1067
1068 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1069 operation, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1070
1071 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1072 if (err != BCM_ERR_OK) {
1073 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 -04001074 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001075 }
1076
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001077 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled PON interface: %d\n", intf_id);
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001078 return Status::OK;
1079}
1080
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001081Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
kesavandc1f2db92020-08-31 15:32:06 +05301082 const char *vendor_id, const char *vendor_specific, uint32_t pir, bool omcc_encryption_mode) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001083 bcmos_errno err = BCM_ERR_OK;
1084 bcmolt_onu_cfg onu_cfg;
1085 bcmolt_onu_key onu_key;
1086 bcmolt_serial_number serial_number; /**< ONU serial number */
1087 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001088
Girish Gowdra24297032020-03-23 12:32:37 -07001089 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1090 bcmolt_onu_state onu_state;
1091
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001092 onu_key.onu_id = onu_id;
1093 onu_key.pon_ni = intf_id;
1094 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1095 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Girish Gowdra24297032020-03-23 12:32:37 -07001096#ifdef TEST_MODE
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001097 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1098 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1099 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1100 // of onu_cfg is passed. This is one-of case where we need to add test specific
1101 // code in production code.
1102 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Girish Gowdra24297032020-03-23 12:32:37 -07001103#else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001104 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Girish Gowdra24297032020-03-23 12:32:37 -07001105#endif
1106 OPENOLT_LOG(INFO, openolt_log_id, "Activate ONU : old state = %d, current state = %d\n",
1107 onu_cfg.data.onu_old_state, onu_cfg.data.onu_state);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001108 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001109 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) {
1110 OPENOLT_LOG(INFO, openolt_log_id, "ONU is already in ACTIVE state, \
1111not processing this request for pon_intf=%d onu_id=%d\n", intf_id, onu_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001112 return Status::OK;
Girish Gowdra24297032020-03-23 12:32:37 -07001113 } else if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_NOT_CONFIGURED &&
1114 onu_cfg.data.onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1115 // We need the ONU to be in NOT_CONFIGURED or INACTIVE state to further process the request
1116 OPENOLT_LOG(ERROR, openolt_log_id, "ONU in an invalid state to process the request, \
1117state=%d pon_intf=%d onu_id=%d\n", onu_cfg.data.onu_state, intf_id, onu_id);
1118 return bcm_to_grpc_err(err, "Failed to activate ONU, invalid ONU state");
1119 }
1120 } else {
1121 // This should never happen. BAL GET should succeed for non-existant ONUs too. The state of such ONUs will be NOT_CONFIGURED
1122 OPENOLT_LOG(ERROR, openolt_log_id, "ONU state query failed pon_intf=%d onu_id=%d\n", intf_id, onu_id);
1123 return bcm_to_grpc_err(err, "onu get failed");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001124 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001125
Girish Gowdra24297032020-03-23 12:32:37 -07001126 // If the ONU is not configured at all we need to first configure it
1127 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_NOT_CONFIGURED) {
1128 OPENOLT_LOG(INFO, openolt_log_id, "Configuring ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001129vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Girish Gowdra24297032020-03-23 12:32:37 -07001130 vendor_specific_to_str(vendor_specific).c_str(), pir);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001131
Girish Gowdra24297032020-03-23 12:32:37 -07001132 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1133 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1134 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1135 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1136 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1137 /*set burst and data profiles to fec disabled*/
1138 if (board_technology == "XGS-PON") {
1139 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1140 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1141 } else if (board_technology == "GPON") {
1142 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1143 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1144 }
1145 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1146 if (err != BCM_ERR_OK) {
1147 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to configure ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
1148 return bcm_to_grpc_err(err, "Failed to configure ONU");
1149 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001150 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001151
Burak Gurdaga0523592021-02-24 15:17:47 +00001152// TODO: MOVE THIS TO A NEW METHOD
kesavandc1f2db92020-08-31 15:32:06 +05301153 if (omcc_encryption_mode == true) {
1154 // set the encryption mode for omci port id
1155 bcmolt_itupon_gem_cfg gem_cfg;
1156 bcmolt_itupon_gem_key key = {};
1157 bcmolt_gem_port_configuration configuration = {};
1158 key.pon_ni = intf_id;
1159 key.gem_port_id = onu_id;
1160 bcmolt_control_state encryption_mode;
1161 encryption_mode = BCMOLT_CONTROL_STATE_ENABLE;
1162 BCMOLT_CFG_INIT(&gem_cfg, itupon_gem, key);
1163 BCMOLT_FIELD_SET(&gem_cfg.data, itupon_gem_cfg_data, encryption_mode, encryption_mode);
1164 err = bcmolt_cfg_set(dev_id, &gem_cfg.hdr);
1165 if(err != BCM_ERR_OK) {
Burak Gurdaga0523592021-02-24 15:17:47 +00001166 OPENOLT_LOG(ERROR, openolt_log_id, "failed to configure omci gem_port encryption mode = %d\n", onu_id);
kesavandc1f2db92020-08-31 15:32:06 +05301167 return bcm_to_grpc_err(err, "Access_Control set ITU PON OMCI Gem port failed");
1168 }
1169 }
Girish Gowdra24297032020-03-23 12:32:37 -07001170 // Now that the ONU is configured, move the ONU to ACTIVE state
1171 memset(&onu_cfg, 0, sizeof(bcmolt_onu_cfg));
1172 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1173 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1174 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
1175 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
1176 onu_state, BCMOLT_ONU_OPERATION_ACTIVE);
1177 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001178 if (err != BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001179 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 +00001180 return bcm_to_grpc_err(err, "Failed to activate ONU");
1181 }
Girish Gowdra24297032020-03-23 12:32:37 -07001182 // ONU will eventually get activated after we have submitted the operation request. The adapter will receive an asynchronous
1183 // ONU_ACTIVATION_COMPLETED_INDICATION
1184
1185 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 +00001186
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001187 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001188}
1189
Jonathan Davis70c21812018-07-19 15:32:10 -04001190Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1191 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001192 bcmos_errno err = BCM_ERR_OK;
1193 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1194 bcmolt_onu_cfg onu_cfg;
1195 bcmolt_onu_key onu_key; /**< Object key. */
1196 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001197
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001198 onu_key.onu_id = onu_id;
1199 onu_key.pon_ni = intf_id;
1200 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1201 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001202 #ifdef TEST_MODE
1203 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1204 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1205 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1206 // of onu_cfg is passed. This is one-of case where we need to add test specific
1207 // code in production code.
1208 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001209 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001210 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001211 #endif
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301212 onu_state = onu_cfg.data.onu_state;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001213 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001214 switch (onu_state) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001215 case BCMOLT_ONU_STATE_ACTIVE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001216 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001217 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001218 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1219 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1220 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001221 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 +00001222 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1223 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301224 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 +00001225 break;
1226 }
Jonathan Davis70c21812018-07-19 15:32:10 -04001227 }
1228
1229 return Status::OK;
1230}
1231
1232Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001233 const char *vendor_id, const char *vendor_specific) {
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301234 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301235 bcmolt_onu_state onu_state;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001236
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001237 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 -05001238 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1239
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001240 // Need to deactivate before removing it (BAL rules)
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001241 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301242
1243 err = get_onu_status((bcmolt_interface)intf_id, onu_id, &onu_state);
1244 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001245 if (onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1246 OPENOLT_LOG(INFO, openolt_log_id, "waiting for onu deactivate complete response: intf_id=%d, onu_id=%d\n",
1247 intf_id, onu_id);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301248 err = wait_for_onu_deactivate_complete(intf_id, onu_id);
1249 if (err) {
1250 OPENOLT_LOG(ERROR, openolt_log_id, "failed to delete onu intf_id %d, onu_id %d\n",
1251 intf_id, onu_id);
1252 return bcm_to_grpc_err(err, "Failed to delete ONU");
1253 }
1254 }
Girish Gowdra24297032020-03-23 12:32:37 -07001255 else {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301256 OPENOLT_LOG(INFO, openolt_log_id, "Onu is Inactive, onu_id: %d, not waiting for onu deactivate complete response\n",
1257 intf_id);
1258 }
1259 }
1260 else {
1261 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch Onu status, onu_id = %d, intf_id = %d, err = %s\n",
1262 onu_id, intf_id, bcmos_strerror(err));
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301263 return bcm_to_grpc_err(err, "Failed to delete ONU");
1264 }
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001265
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001266 bcmolt_onu_cfg cfg_obj;
1267 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001268
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001269 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 -04001270 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001271
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001272 key.onu_id = onu_id;
1273 key.pon_ni = intf_id;
1274 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001275
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301276 err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001277 if (err != BCM_ERR_OK)
1278 {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001279 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 -04001280 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1281 }
1282
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301283 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 +00001284 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001285}
1286
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001287#define MAX_CHAR_LENGTH 20
1288#define MAX_OMCI_MSG_LENGTH 44
1289Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001290 bcmolt_bin_str buf = {};
1291 bcmolt_onu_cpu_packets omci_cpu_packets;
1292 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001293
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001294 key.pon_ni = intf_id;
1295 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001296
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001297 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1298 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1299 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001300
1301 // ???
1302 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1303 buf.len = MAX_OMCI_MSG_LENGTH;
1304 } else {
1305 buf.len = pkt.size()/2;
1306 }
1307
1308 /* Send the OMCI packet using the BAL remote proxy API */
1309 uint16_t idx1 = 0;
1310 uint16_t idx2 = 0;
1311 uint8_t arraySend[buf.len];
1312 char str1[MAX_CHAR_LENGTH];
1313 char str2[MAX_CHAR_LENGTH];
1314 memset(&arraySend, 0, buf.len);
1315
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001316 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1317 sprintf(str1,"%c", pkt[idx1]);
1318 sprintf(str2,"%c", pkt[++idx1]);
1319 strcat(str1,str2);
1320 arraySend[idx2] = strtol(str1, NULL, 16);
1321 }
1322
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001323 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1324 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001325
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001326 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1327 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1328 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001329
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001330 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001331 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001332 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 +00001333 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001334 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001335 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 -05001336 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001337 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001338 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001339
1340 return Status::OK;
1341}
1342
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001343Status 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 +00001344 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1345 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1346 bcmolt_bin_str buf = {};
1347 bcmolt_gem_port_id gem_port_id_array[1];
1348 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001349
Craig Lutgen967a1d02018-11-27 10:41:51 -06001350 if (port_no > 0) {
1351 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001352 if (gemport_id == 0) {
1353 bcmos_fastlock_lock(&data_lock);
1354 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1355 // Pick any flow that is mapped with the same port_no.
1356 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1357 if (it != port_to_flows.end() && !it->second.empty()) {
1358 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1359 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1360 if (fit != flowid_to_gemport.end()) {
1361 found = true;
1362 gemport_id = fit->second;
1363 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001364 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001365 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001366
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001367 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001368 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 -08001369 onu_id, port_no, intf_id);
1370 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1371 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001372 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 -08001373 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001374 }
1375
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001376 gem_port_id_array[0] = gemport_id;
1377 gem_port_list.len = 1;
1378 gem_port_list.arr = gem_port_id_array;
1379 buf.len = pkt.size();
1380 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1381 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1382
1383 /* init the API struct */
1384 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1385 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1386 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1387 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1388 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1389
1390 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1391 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1392
1393 /* call API */
1394 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001395 }
1396 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001397 //TODO: Port No is 0, it is coming sender requirement.
1398 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1399 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001400 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001401 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001402
1403 return Status::OK;
1404}
1405
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001406Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001407 bcmolt_flow_key key = {}; /* declare key */
1408 bcmolt_bin_str buffer = {};
1409 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001410
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001411 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
Girish Gowdra252f4972020-09-07 21:24:01 -07001412 bcmolt_flow_id flow_id = INVALID_FLOW_ID;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001413
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001414 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1415 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1416 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1417 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1418 key.flow_id = flow_id;
1419 else {
Jason Huang09b73ea2020-01-08 17:52:05 +08001420 if (flow_id_counters) {
1421 std::map<flow_pair, int>::iterator it;
1422 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1423 int flow_index = it->first.first;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001424 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1425 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1426 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1427 key.flow_id = flow_index;
1428 break;
1429 }
1430 }
1431 }
1432 else {
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001433 OPENOLT_LOG(ERROR, openolt_log_id, "no flow id found for uplink packetout\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001434 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1435 }
1436 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001437
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001438 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001439
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001440 /* Initialize the API struct. */
1441 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001442
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001443 buffer.len = pkt.size();
1444 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1445 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1446 if (buffer.arr == NULL) {
1447 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1448 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1449 }
1450 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1451
1452 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1453 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001454 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 -05001455 return bcm_to_grpc_err(BCM_ERR_SYSCALL_ERR, "Error sending packets via nni port");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001456 } else {
1457 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1458 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001459
1460 return Status::OK;
1461}
Girish Gowdra252f4972020-09-07 21:24:01 -07001462
Burak Gurdaga0523592021-02-24 15:17:47 +00001463bool get_aes_flag_for_gem_port(const google::protobuf::Map<unsigned int, bool> &gemport_to_aes, uint32_t gemport_id) {
1464 bool aes_flag = false;
1465 for (google::protobuf::Map<unsigned int, bool>::const_iterator it=gemport_to_aes.begin(); it!=gemport_to_aes.end(); it++) {
1466 if (it->first == gemport_id) {
1467 aes_flag = it->second;
1468 break;
1469 }
1470 }
1471 return aes_flag;
1472}
1473
Girish Gowdra252f4972020-09-07 21:24:01 -07001474Status FlowAddWrapper_(const ::openolt::Flow* request) {
1475
1476 int32_t access_intf_id = request->access_intf_id();
1477 int32_t onu_id = request->onu_id();
1478 int32_t uni_id = request->uni_id();
1479 uint32_t port_no = request->port_no();
1480 uint64_t voltha_flow_id = request->flow_id();
1481 uint64_t symmetric_voltha_flow_id = request->symmetric_flow_id();
1482 const std::string flow_type = request->flow_type();
1483 int32_t alloc_id = request->alloc_id();
1484 int32_t network_intf_id = request->network_intf_id();
1485 int32_t gemport_id = request->gemport_id();
1486 const ::openolt::Classifier& classifier = request->classifier();
1487 const ::openolt::Action& action = request->action();
1488 int32_t priority = request->priority();
1489 uint64_t cookie = request->cookie();
1490 int32_t group_id = request->group_id();
1491 uint32_t tech_profile_id = request->tech_profile_id();
1492 bool replicate_flow = request->replicate_flow();
1493 const google::protobuf::Map<unsigned int, unsigned int> &pbit_to_gemport = request->pbit_to_gemport();
Burak Gurdaga0523592021-02-24 15:17:47 +00001494 const google::protobuf::Map<unsigned int, bool> &gemport_to_aes = request->gemport_to_aes();
Girish Gowdra252f4972020-09-07 21:24:01 -07001495 uint16_t flow_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001496 bool enable_encryption;
Girish Gowdra252f4972020-09-07 21:24:01 -07001497
1498 // The intf_id variable defaults to access(PON) interface ID.
1499 // For trap-from-nni flow where access interface ID is not valid , change it to NNI interface ID
1500 // This intf_id identifies the pool from which we get the flow_id
1501 uint32_t intf_id = access_intf_id;
1502 if (onu_id < 1) {
1503 onu_id = 1;
1504 }
1505 if (access_intf_id < 0) {
1506 intf_id = network_intf_id;
1507 }
1508
1509 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)
1510 // This is the case of voltha_flow_id (not symmetric_voltha_flow_id)
1511 if (is_voltha_flow_installed(voltha_flow_id)) {
1512 OPENOLT_LOG(INFO, openolt_log_id, "voltha_flow_id=%lu, already installed\n", voltha_flow_id);
1513 return ::Status(grpc::StatusCode::ALREADY_EXISTS, "voltha-flow-already-installed");
1514 }
1515
Girish Gowdra252f4972020-09-07 21:24:01 -07001516 // This is the case of symmetric_voltha_flow_id
1517 // If symmetric_voltha_flow_id is available and valid in the Flow message,
1518 // check if it is installed, and use the corresponding device_flow_id
1519 if (symmetric_voltha_flow_id > 0 && is_voltha_flow_installed(symmetric_voltha_flow_id)) { // symmetric flow found
1520 OPENOLT_LOG(INFO, openolt_log_id, "symmetric flow and the symmetric flow is installed\n");
1521 const device_flow_params *dev_fl_symm_params;
1522 dev_fl_symm_params = get_device_flow_params(symmetric_voltha_flow_id);
1523 if (dev_fl_symm_params == NULL) {
1524 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)
1525 return ::Status(grpc::StatusCode::INTERNAL, "symmetric-flow-details-not-found");
1526 }
1527
1528 if (!replicate_flow) { // No flow replication
1529 flow_id = dev_fl_symm_params[0].flow_id;
1530 gemport_id = dev_fl_symm_params[0].gemport_id; // overwrite the gemport with symmetric flow gemport
1531 // Should be same as what is coming in this request.
Burak Gurdaga0523592021-02-24 15:17:47 +00001532 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001533 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1534 cl.set_o_pbits(dev_fl_symm_params[0].pbit);
1535 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1536 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001537 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001538 if (st.error_code() == grpc::StatusCode::OK) {
1539 device_flow dev_fl;
1540 dev_fl.is_flow_replicated = false;
1541 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1542 dev_fl.voltha_flow_id = voltha_flow_id;
1543 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params));
1544 // update voltha flow to cache
1545 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1546 }
1547 return st;
1548 } else { // Flow to be replicated
1549 OPENOLT_LOG(INFO, openolt_log_id,"symmetric flow and replication is needed\n");
1550 for (uint8_t i=0; i<NUMBER_OF_REPLICATED_FLOWS; i++) {
1551 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1552 flow_id = dev_fl_symm_params[i].flow_id;
1553 gemport_id = dev_fl_symm_params[i].gemport_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001554 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001555 cl.set_o_pbits(dev_fl_symm_params[i].pbit);
1556 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdrade65ab42020-12-17 23:08:43 -08001557 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001558 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001559 if (st.error_code() != grpc::StatusCode::OK && st.error_code() != grpc::StatusCode::ALREADY_EXISTS) {
1560 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);
1561 // On failure remove any successfully replicated flows installed so far for the voltha_flow_id
1562 if (i > 0) {
1563 for (int8_t j = i-1; j >= 0; j--) {
1564 flow_id = dev_fl_symm_params[j].flow_id;
1565 FlowRemove_(flow_id, flow_type);
1566 }
1567 }
1568 return st;
1569 }
1570 }
1571 device_flow dev_fl;
1572 dev_fl.is_flow_replicated = true;
1573 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1574 dev_fl.voltha_flow_id = voltha_flow_id;
1575 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params)*NUMBER_OF_REPLICATED_FLOWS);
1576 // update voltha flow to cache
1577 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1578 }
1579 } else { // No symmetric flow found
1580 if (!replicate_flow) { // No flow replication
1581 OPENOLT_LOG(INFO, openolt_log_id, "not a symmetric flow and replication is not needed\n");
1582 flow_id = get_flow_id();
1583 if (flow_id == INVALID_FLOW_ID) {
1584 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocated flow id for voltha-flow-id=%lu\n", voltha_flow_id);
1585 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1586 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001587 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001588 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1589 flow_type, alloc_id, network_intf_id, gemport_id, classifier,
Burak Gurdaga0523592021-02-24 15:17:47 +00001590 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001591 if (st.error_code() == grpc::StatusCode::OK) {
1592 device_flow dev_fl;
1593 dev_fl.is_flow_replicated = false;
1594 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // Invalid
1595 dev_fl.voltha_flow_id = voltha_flow_id;
1596 dev_fl.params[0].flow_id = flow_id;
1597 dev_fl.params[0].gemport_id = gemport_id;
1598 dev_fl.params[0].pbit = classifier.o_pbits();
1599 // update voltha flow to cache
1600 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1601 } else {
1602 // Free the flow id on failure
1603 free_flow_id(flow_id);
1604 }
1605 return st;
1606 } else { // Flow to be replicated
1607 OPENOLT_LOG(INFO, openolt_log_id,"not a symmetric flow and replication is needed\n");
1608 if (pbit_to_gemport.size() != NUMBER_OF_PBITS) {
1609 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pbit-to-gemport map size=%lu", pbit_to_gemport.size())
1610 return ::Status(grpc::StatusCode::OUT_OF_RANGE, "pbit-to-gemport-map-len-invalid-for-flow-replication");
1611 }
1612 uint16_t flow_ids[NUMBER_OF_REPLICATED_FLOWS];
1613 device_flow dev_fl;
1614 if (get_flow_ids(NUMBER_OF_REPLICATED_FLOWS, flow_ids)) {
1615 uint8_t cnt = 0;
1616 dev_fl.is_flow_replicated = true;
1617 dev_fl.voltha_flow_id = voltha_flow_id;
1618 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // invalid
1619 for (google::protobuf::Map<unsigned int, unsigned int>::const_iterator it=pbit_to_gemport.begin(); it!=pbit_to_gemport.end(); it++) {
1620 dev_fl.params[cnt].flow_id = flow_ids[cnt];
1621 dev_fl.params[cnt].pbit = it->first;
1622 dev_fl.params[cnt].gemport_id = it->second;
1623
1624 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1625 flow_id = dev_fl.params[cnt].flow_id;
1626 gemport_id = dev_fl.params[cnt].gemport_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001627 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001628 cl.set_o_pbits(dev_fl.params[cnt].pbit);
1629 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1630 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001631 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001632 if (st.error_code() != grpc::StatusCode::OK) {
1633 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);
1634 // Remove any successfully replicated flows installed so far for the voltha_flow_id
1635 if (cnt > 0) {
1636 for (int8_t j = cnt-1; j >= 0; j--) {
1637 flow_id = dev_fl.params[j].flow_id;
1638 FlowRemove_(flow_id, flow_type);
1639 }
1640 }
1641 // Free up all the flow IDs on failure
1642 free_flow_ids(NUMBER_OF_REPLICATED_FLOWS, flow_ids);
1643 return st;
1644 }
1645 cnt++;
1646 }
1647 // On successful flow replication update voltha-flow-id to device-flow map to cache
1648 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1649 } else {
1650 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocate flow ids for replication voltha-flow-id=%lu\n", voltha_flow_id);
1651 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1652 }
1653 }
1654 }
1655
1656 return Status::OK;
1657}
1658
1659
Craig Lutgen967a1d02018-11-27 10:41:51 -06001660Status 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 +00001661 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001662 int32_t alloc_id, int32_t network_intf_id,
1663 int32_t gemport_id, const ::openolt::Classifier& classifier,
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001664 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie,
Burak Gurdaga0523592021-02-24 15:17:47 +00001665 int32_t group_id, uint32_t tech_profile_id, bool aes_enabled) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001666 bcmolt_flow_cfg cfg;
1667 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001668 int32_t o_vid = -1;
1669 bool single_tag = false;
1670 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001671 bcmolt_classifier c_val = { };
1672 bcmolt_action a_val = { };
1673 bcmolt_tm_queue_ref tm_val = { };
1674 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05001675 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001676
Jason Huang09b73ea2020-01-08 17:52:05 +08001677 OPENOLT_LOG(INFO, openolt_log_id, "flow add received for flow_id=%u, flow_type=%s\n", flow_id, flow_type.c_str());
1678
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001679 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001680 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001681 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001682 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001683 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001684 } else if (flow_type.compare(multicast) == 0) {
1685 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001686 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001687 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001688 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001689 }
1690
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001691 BCMOLT_CFG_INIT(&cfg, flow, key);
1692 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001693
Jason Huang09b73ea2020-01-08 17:52:05 +08001694 if (action.cmd().trap_to_host()) {
Girish Gowdra1935e6a2020-10-31 21:48:22 -07001695 Status resp = handle_acl_rule_install(onu_id, flow_id, gemport_id, flow_type, access_intf_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001696 network_intf_id, classifier);
Jason Huang09b73ea2020-01-08 17:52:05 +08001697 return resp;
1698 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001699
1700 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1701
1702 if (access_intf_id >= 0 && network_intf_id >= 0) {
1703 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1704 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1705 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08001706 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1707 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001708 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1709 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1710 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1711 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1712 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001713 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001714 } else {
1715 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
1716 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001717 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001718
Burak Gurdaga0523592021-02-24 15:17:47 +00001719 if (onu_id >= ONU_ID_START) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001720 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
1721 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001722 if (gemport_id >= GEM_PORT_ID_START) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001723 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
1724 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001725 if (gemport_id >= GEM_PORT_ID_START && port_no != 0) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001726 bcmos_fastlock_lock(&data_lock);
1727 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
1728 port_to_flows[port_no].insert(key.flow_id);
1729 flowid_to_gemport[key.flow_id] = gemport_id;
1730 }
1731 else
1732 {
1733 flowid_to_port[key.flow_id] = port_no;
1734 }
1735 bcmos_fastlock_unlock(&data_lock, 0);
1736 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001737
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001738 if (priority_value >= 0) {
1739 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
1740 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301741
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001742 } else { // MULTICAST FLOW
1743 if (group_id >= 0) {
1744 BCMOLT_MSG_FIELD_SET(&cfg, group_id, group_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001745 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001746 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1747 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001748 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001749
1750 {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001751 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001752 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001753 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
1754 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001755 }
1756
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001757 if (classifier.dst_mac().size() > 0) {
1758 bcmos_mac_address d_mac = {};
1759 bcmos_mac_address_init(&d_mac);
1760 memcpy(d_mac.u8, classifier.dst_mac().data(), sizeof(d_mac.u8));
1761 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_mac %02x:%02x:%02x:%02x:%02x:%02x\n", d_mac.u8[0],
1762 d_mac.u8[1], d_mac.u8[2], d_mac.u8[3], d_mac.u8[4], d_mac.u8[5]);
1763 BCMOLT_FIELD_SET(&c_val, classifier, dst_mac, d_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001764 }
1765
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001766 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001767 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001768 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001769 }
1770 */
1771
1772 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001773 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
1774 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001775 }
1776
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001777 if (classifier.dst_ip()) {
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08001778 bcmos_ipv4_address d_ip = {};
1779 bcmos_ipv4_address_init(&d_ip);
1780 d_ip.u32 = classifier.dst_ip();
1781 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_ip %04x\n", d_ip.u32);
1782 BCMOLT_FIELD_SET(&c_val, classifier, dst_ip, d_ip);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001783 }
1784
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08001785 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001786 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001787 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001788 }
1789 */
1790
1791 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001792 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
1793 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001794 }
1795
1796 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001797 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
1798 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001799 }
1800
1801 if (!classifier.pkt_tag_type().empty()) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001802 if (classifier.o_vid()) {
1803 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
1804 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
1805 }
1806
1807 if (classifier.i_vid()) {
1808 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
1809 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
1810 }
1811
1812 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
1813 if (classifier.pkt_tag_type().compare("untagged") == 0) {
1814 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
1815 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
1816 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
1817 single_tag = true;
1818
1819 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301820 // OpenOlt adapter will send 0xFF in case of no pbit classification
1821 // If it is any other value (0 to 7), it is for outer pbit classification.
1822 // OpenFlow protocol does not provide inner pbit classification (in case of double tagged packets),
1823 // and VOLTHA has not used any workaround to solve this problem (for ex: use metadata field).
1824 // Also there exists no use case for i-pbit classification, so we can safely ignore this for now.
1825 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001826 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301827 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001828 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
1829 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001830
Jason Huang09b73ea2020-01-08 17:52:05 +08001831 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301832 // Same comments as in case of "single_tag" packets.
1833 // 0xFF means no pbit classification, otherwise a valid PCP (0 to 7).
1834 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001835 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301836 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001837 }
1838 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001839 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001840 }
1841
Jason Huang09b73ea2020-01-08 17:52:05 +08001842 const ::openolt::ActionCmd& cmd = action.cmd();
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001843
Jason Huang09b73ea2020-01-08 17:52:05 +08001844 if (cmd.add_outer_tag()) {
1845 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
1846 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001847 }
1848
Jason Huang09b73ea2020-01-08 17:52:05 +08001849 if (cmd.remove_outer_tag()) {
1850 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
1851 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
1852 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301853
Jason Huang09b73ea2020-01-08 17:52:05 +08001854 if (action.o_vid()) {
1855 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
1856 o_vid = action.o_vid();
1857 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
1858 }
1859
1860 if (action.o_pbits()) {
1861 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
1862 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
1863 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301864
Jason Huang09b73ea2020-01-08 17:52:05 +08001865 if (action.i_vid()) {
1866 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
1867 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
1868 }
1869
1870 if (action.i_pbits()) {
1871 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
1872 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
1873 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301874
Jason Huang09b73ea2020-01-08 17:52:05 +08001875 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
1876
Burak Gurdaga0523592021-02-24 15:17:47 +00001877 if ((access_intf_id >= 0) && (onu_id >= ONU_ID_START)) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001878 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
1879 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00001880 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 +00001881
Jason Huang09b73ea2020-01-08 17:52:05 +08001882 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1883 // Queue 0 on DS subscriber scheduler
1884 tm_val.queue_id = 0;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001885
Jason Huang09b73ea2020-01-08 17:52:05 +08001886 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1887 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1888 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001889
Jason Huang09b73ea2020-01-08 17:52:05 +08001890 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1891 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1892 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001893
Jason Huang09b73ea2020-01-08 17:52:05 +08001894 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1895 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
1896 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 +00001897
Jason Huang09b73ea2020-01-08 17:52:05 +08001898 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1899 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1900 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1901 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 +00001902
Jason Huang09b73ea2020-01-08 17:52:05 +08001903 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
1904 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1905 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1906 }
1907 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
1908 // NNI Scheduler ID
1909 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1910 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1911 // Queue 0 on NNI scheduler
1912 tm_val.queue_id = 0;
1913 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1914 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1915 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001916
Jason Huang09b73ea2020-01-08 17:52:05 +08001917 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 +00001918 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1919 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1920
Jason Huang09b73ea2020-01-08 17:52:05 +08001921 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1922 /* Fetch TM QMP ID mapped to US NNI scheduler */
1923 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
1924 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1925 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1926 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1927 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 +00001928
Jason Huang09b73ea2020-01-08 17:52:05 +08001929 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 +00001930 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1931 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001932 }
Shad Ansari39739bc2018-09-13 21:38:37 +00001933 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301934 } else {
1935 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1936 tm_val.queue_id = 0;
1937
1938 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
1939 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1940 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
1941
1942 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1943 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
1944 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00001945 }
1946
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001947 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001948
Girish Gowdra252f4972020-09-07 21:24:01 -07001949#ifndef SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001950 // BAL 3.1 supports statistics only for unicast flows.
1951 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1952 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
1953 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001954#endif // SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001955
Girish Gowdra252f4972020-09-07 21:24:01 -07001956#ifndef SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001957#ifdef FLOW_CHECKER
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001958 //Flow Checker, To avoid duplicate flow.
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001959 if (flow_id_counters != 0) {
1960 bool b_duplicate_flow = false;
Jason Huang09b73ea2020-01-08 17:52:05 +08001961 std::map<flow_pair, int>::iterator it;
1962
1963 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1964 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(it->first.first, it->first.second, ONU_ID)) && \
1965 (key.flow_type == it->first.second) && \
1966 (cfg.data.svc_port_id == get_flow_status(it->first.first, it->first.second, SVC_PORT_ID)) && \
1967 (cfg.data.priority == get_flow_status(it->first.first, it->first.second, PRIORITY)) && \
1968 (cfg.data.cookie == get_flow_status(it->first.first, it->first.second, COOKIE)) && \
1969 (cfg.data.ingress_intf.intf_type == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_TYPE)) && \
1970 (cfg.data.ingress_intf.intf_id == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_ID)) && \
1971 (cfg.data.egress_intf.intf_type == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_TYPE)) && \
1972 (cfg.data.egress_intf.intf_id == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_ID)) && \
1973 (c_val.o_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_VID)) && \
1974 (c_val.o_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_PBITS)) && \
1975 (c_val.i_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_VID)) && \
1976 (c_val.i_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_PBITS)) && \
1977 (c_val.ether_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_ETHER_TYPE)) && \
1978 (c_val.ip_proto == get_flow_status(it->first.first, it->first.second, CLASSIFIER_IP_PROTO)) && \
1979 (c_val.src_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_SRC_PORT)) && \
1980 (c_val.dst_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_DST_PORT)) && \
1981 (c_val.pkt_tag_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_PKT_TAG_TYPE)) && \
1982 (cfg.data.egress_qos.type == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TYPE)) && \
1983 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_QUEUE_ID)) && \
1984 (cfg.data.egress_qos.tm_sched.id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TM_SCHED_ID)) && \
1985 (a_val.cmds_bitmask == get_flow_status(it->first.first, it->first.second, ACTION_CMDS_BITMASK)) && \
1986 (a_val.o_vid == get_flow_status(it->first.first, it->first.second, ACTION_O_VID)) && \
1987 (a_val.i_vid == get_flow_status(it->first.first, it->first.second, ACTION_I_VID)) && \
1988 (a_val.o_pbits == get_flow_status(it->first.first, it->first.second, ACTION_O_PBITS)) && \
1989 (a_val.i_pbits == get_flow_status(it->first.first, it->first.second, ACTION_I_PBITS)) && \
1990 (cfg.data.state == get_flow_status(it->first.first, it->first.second, STATE)) && \
1991 (cfg.data.group_id == get_flow_status(it->first.first, it->first.second, GROUP_ID));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001992#ifdef SHOW_FLOW_PARAM
1993 // Flow Parameter
1994 FLOW_PARAM_LOG();
1995#endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001996 if (b_duplicate_flow) {
1997 FLOW_LOG(WARNING, "Flow duplicate", 0);
1998 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
1999 }
2000 }
2001 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002002#endif // FLOW_CHECKER
2003#endif // SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002004
2005 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2006 if (err) {
2007 FLOW_LOG(ERROR, "Flow add failed", err);
2008 return bcm_to_grpc_err(err, "flow add failed");
2009 } else {
2010 FLOW_LOG(INFO, "Flow add ok", err);
2011 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002012 flow_map[std::pair<int, int>(key.flow_id,key.flow_type)] = flow_map.size();
2013 flow_id_counters = flow_map.size();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002014 bcmos_fastlock_unlock(&data_lock, 0);
Girish Gowdra252f4972020-09-07 21:24:01 -07002015
2016 }
Burak Gurdaga0523592021-02-24 15:17:47 +00002017
2018 /*
2019 Enable AES encryption on GEM ports if they are used in downstream unicast flows.
2020 Rationale: We can't do upstream encryption in GPON. This change addresses the common denominator (and also minimum viable)
2021 use case for both technologies which is downstream unicast GEM port encryption. Since the downstream traffic is inherently
2022 broadcast to all the ONUs behind a PON port, encrypting the individual subscriber traffic in this direction is important
2023 and considered good enough in terms of security (See Section 12.1 of G.984.3). For upstream unicast and downstream multicast
2024 GEM encryption, we need to make additional changes specific to XGSPON. This will be done as a future work.
2025 */
2026 if (aes_enabled && (access_intf_id >= 0) && (gemport_id >= GEM_PORT_ID_START) && (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM)) {
2027 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);
2028 enable_encryption_for_gem_port(access_intf_id, gemport_id);
2029 } else {
2030 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);
2031 }
2032
Girish Gowdra252f4972020-09-07 21:24:01 -07002033 return Status::OK;
2034}
2035
2036Status FlowRemoveWrapper_(const ::openolt::Flow* request) {
2037 const std::string flow_type = request->flow_type();
2038 uint64_t voltha_flow_id = request->flow_id();
2039 Status st;
2040
2041 // If Voltha flow is not installed, return fail
2042 if (! is_voltha_flow_installed(voltha_flow_id)) {
2043 OPENOLT_LOG(ERROR, openolt_log_id, "voltha_flow_id=%lu not found\n", voltha_flow_id);
2044 return ::Status(grpc::StatusCode::NOT_FOUND, "voltha-flow-not-found");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002045 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04002046
Girish Gowdra252f4972020-09-07 21:24:01 -07002047 const device_flow *dev_fl = get_device_flow(voltha_flow_id);
2048 if (dev_fl == NULL) {
2049 OPENOLT_LOG(ERROR, openolt_log_id, "device flow for voltha_flow_id=%lu in the cache is NULL\n", voltha_flow_id);
2050 return ::Status(grpc::StatusCode::INTERNAL, "device-flow-null-in-cache");
2051 }
2052 if (dev_fl->is_flow_replicated) {
2053 // Note: Here we are ignoring FlowRemove failures
2054 for (int i=0; i<NUMBER_OF_REPLICATED_FLOWS; i++) {
2055 st = FlowRemove_(dev_fl->params[i].flow_id, flow_type);
2056 if (st.error_code() == grpc::StatusCode::OK) {
2057 free_flow_id(dev_fl->params[i].flow_id);
2058 }
2059 }
2060 } else {
2061 // Note: Here we are ignoring FlowRemove failures
2062 st = FlowRemove_(dev_fl->params[0].flow_id, flow_type);
2063 if (st.error_code() == grpc::StatusCode::OK) {
2064 free_flow_id(dev_fl->params[0].flow_id);
2065 }
2066 }
2067 // remove the flow from cache on voltha flow removal
2068 remove_voltha_flow_from_cache(voltha_flow_id);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002069 return Status::OK;
2070}
2071
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002072Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
2073
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002074 bcmolt_flow_cfg cfg;
2075 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002076
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002077 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002078 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002079 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002080 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002081 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002082 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002083 } else if(flow_type.compare(multicast) == 0) {
2084 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002085 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002086 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002087 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
2088 }
2089
Jason Huang09b73ea2020-01-08 17:52:05 +08002090 OPENOLT_LOG(INFO, openolt_log_id, "flow remove received for flow_id=%u, flow_type=%s\n",
2091 flow_id, flow_type.c_str());
2092
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002093 bcmos_fastlock_lock(&acl_packet_trap_handler_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002094 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
2095 int32_t gemport_id = -1;
2096 int32_t intf_id = -1;
2097 int16_t acl_id = -1;
2098 if (flow_to_acl_map.count(fl_id_fl_dir) > 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002099
2100 acl_id_intf_id ac_id_if_id = flow_to_acl_map[fl_id_fl_dir];
2101 acl_id = std::get<0>(ac_id_if_id);
2102 intf_id = std::get<1>(ac_id_if_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002103 // cleanup acl only if it is a valid acl. If not valid acl, it may be datapath flow.
2104 if (acl_id >= 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002105 Status resp = handle_acl_rule_cleanup(acl_id, intf_id, flow_type);
Jason Huang09b73ea2020-01-08 17:52:05 +08002106 if (resp.ok()) {
2107 OPENOLT_LOG(INFO, openolt_log_id, "acl removed ok for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2108 flow_to_acl_map.erase(fl_id_fl_dir);
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002109
2110 // 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
2111 if (trap_to_host_pkt_info_with_vlan_for_flow_id.count(flow_id) > 0) {
2112 trap_to_host_pkt_info_with_vlan pkt_info_with_vlan = trap_to_host_pkt_info_with_vlan_for_flow_id[flow_id];
2113 // Formulate the trap_to_host_pkt_info tuple key
2114 trap_to_host_pkt_info pkt_info(std::get<0>(pkt_info_with_vlan),
2115 std::get<1>(pkt_info_with_vlan),
2116 std::get<2>(pkt_info_with_vlan),
2117 std::get<3>(pkt_info_with_vlan));
2118 // Extract the value corresponding to trap_to_host_pkt_info key from trap_to_host_vlan_ids_for_trap_to_host_pkt_info
2119 // The value is a list of vlan_ids for the given trap_to_host_pkt_info key
2120 // Remove the vlan_id from the list that corresponded to the flow being removed.
2121 if (trap_to_host_vlan_ids_for_trap_to_host_pkt_info.count(pkt_info) > 0) {
2122 trap_to_host_vlan_ids_for_trap_to_host_pkt_info[pkt_info].remove(std::get<4>(pkt_info_with_vlan));
2123 } else {
2124 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",
2125 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));
2126 }
2127
2128 } else {
2129 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);
2130 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002131 } else {
2132 OPENOLT_LOG(ERROR, openolt_log_id, "acl remove error for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2133 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002134 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002135 return resp;
2136 }
2137 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002138 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002139
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002140 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002141 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002142 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002143 flowid_to_gemport.erase(key.flow_id);
2144 port_to_flows[port_no].erase(key.flow_id);
2145 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
2146 }
2147 else
2148 {
2149 flowid_to_port.erase(key.flow_id);
2150 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002151 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002152
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002153 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002154
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002155 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002156 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002157 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 -04002158 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
2159 }
2160
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002161 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002162 if (flow_id_counters != 0) {
2163 std::map<flow_pair, int>::iterator it;
2164 for(it = flow_map.begin(); it != flow_map.end(); it++) {
2165 if (it->first.first == flow_id && it->first.second == key.flow_type) {
2166 flow_id_counters -= 1;
2167 flow_map.erase(it);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002168 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002169 }
2170 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002171 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
2172
Jason Huang09b73ea2020-01-08 17:52:05 +08002173 flow_to_acl_map.erase(fl_id_fl_dir);
2174
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002175 bcmos_fastlock_unlock(&data_lock, 0);
2176
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002177 return Status::OK;
2178}
2179
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002180bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
2181 bcmos_errno err;
2182 bcmolt_tm_sched_cfg tm_sched_cfg;
2183 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2184 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
2185
Jason Huangbf45ffb2019-10-30 17:29:02 +08002186 //check TM scheduler has configured or not
2187 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2188 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002189 #ifdef TEST_MODE
2190 // It is impossible to mock the setting of tm_sched_cfg.data.state because
2191 // the actual bcmolt_cfg_get passes the address of tm_sched_cfg.hdr and we cannot
2192 // set the tm_sched_cfg.data.state. So a new stub function is created and address
2193 // of tm_sched_cfg is passed. This is one-of case where we need to add test specific
2194 // code in production code.
2195 err = bcmolt_cfg_get__tm_sched_stub(dev_id, &tm_sched_cfg);
2196 #else
Jason Huangbf45ffb2019-10-30 17:29:02 +08002197 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002198 #endif
Jason Huangbf45ffb2019-10-30 17:29:02 +08002199 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002200 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 +08002201 return err;
2202 }
2203 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
2204 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
2205 return BCM_ERR_OK;
2206 }
2207
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002208 // bcmbal_tm_sched_owner
2209 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2210
2211 /**< The output of the tm_sched object instance */
2212 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
2213
2214 if (direction.compare(upstream) == 0) {
2215 // In upstream it is NNI scheduler
2216 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
2217 } else if (direction.compare(downstream) == 0) {
2218 // In downstream it is PON scheduler
2219 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2220 }
2221
2222 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2223
2224 // bcmbal_tm_sched_type
2225 // set the deafult policy to strict priority
2226 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2227
2228 // num_priorities: Max number of strict priority scheduling elements
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002229 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, NUM_OF_PRIORITIES);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002230
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002231 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2232 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002233 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
2234 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002235 return err;
2236 }
2237
2238 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2239 direction.c_str(), tm_sched_key.id, intf_id);
2240 return BCM_ERR_OK;
2241}
2242
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002243bcmos_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 -07002244 uint32_t alloc_id, ::tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
2245 ::tech_profile::SchedulingPolicy sched_policy, ::tech_profile::TrafficShapingInfo tf_sh_info,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002246 uint32_t tech_profile_id) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002247
2248 bcmos_errno err;
2249
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002250 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002251 bcmolt_tm_sched_cfg tm_sched_cfg;
2252 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002253 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 -04002254
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002255 // bcmbal_tm_sched_owner
2256 // In downstream it is sub_term scheduler
2257 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002258
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002259 /**< The output of the tm_sched object instance */
2260 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002261
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002262 // bcmbal_tm_sched_parent
2263 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2264 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
2265 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 +00002266 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002267 be achieved using the' virtual' type of attachment.
2268 tm_sched_owner.u.sub_term.intf_id = intf_id;
2269 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2270 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002271
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002272 // 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);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002275
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002276 // num_priorities: Max number of strict priority scheduling elements
2277 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002278
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002279 // bcmbal_tm_shaping
2280 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2281 uint32_t cir = tf_sh_info.cir();
2282 uint32_t pir = tf_sh_info.pir();
2283 uint32_t burst = tf_sh_info.pbs();
2284 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2285 cir, pir, burst);
2286 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2287 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2288 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2289 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2290 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2291 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002292 }
2293
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002294 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002295 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002296 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002297intf_id %d, onu_id %d, uni_id %d, port_no %u, err = %s\n", tm_sched_key.id, intf_id, onu_id, uni_id, \
2298port_no, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002299 return err;
2300 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002301 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2302uni_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 -08002303
2304 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002305 bcmolt_itupon_alloc_cfg cfg;
2306 bcmolt_itupon_alloc_key key = { };
2307 key.pon_ni = intf_id;
2308 key.alloc_id = alloc_id;
2309 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
Burak Gurdag03919c72020-02-04 22:46:57 +00002310 int pir_bw = tf_sh_info.pir()*125; // conversion from kbps to bytes/sec
2311 int cir_bw = tf_sh_info.cir()*125; // conversion from kbps to bytes/sec
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002312 //offset to match bandwidth granularity
2313 int offset_pir_bw = pir_bw%bw_granularity;
2314 int offset_cir_bw = cir_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002315
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002316 pir_bw = pir_bw - offset_pir_bw;
2317 cir_bw = cir_bw - offset_cir_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002318
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002319 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002320
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002321 switch (additional_bw) {
2322 case 2: //AdditionalBW_BestEffort
2323 if (pir_bw == 0) {
2324 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2325%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002326 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002327 } else if (pir_bw < cir_bw) {
2328 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2329bandwidth (%d)\n", pir_bw, cir_bw);
2330 return BCM_ERR_PARM;
2331 } else if (pir_bw == cir_bw) {
2332 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2333bandwidth for additional bandwidth eligibility of type best_effort\n");
2334 return BCM_ERR_PARM;
2335 }
2336 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2337 break;
2338 case 1: //AdditionalBW_NA
2339 if (pir_bw == 0) {
2340 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2341%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2342 return BCM_ERR_PARM;
2343 } else if (cir_bw == 0) {
2344 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2345additional bandwidth eligibility of type Non-Assured (NA)\n");
2346 return BCM_ERR_PARM;
2347 } else if (pir_bw < cir_bw) {
2348 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2349bandwidth (%d)\n", pir_bw, cir_bw);
2350 return BCM_ERR_PARM;
2351 } else if (pir_bw == cir_bw) {
2352 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2353bandwidth for additional bandwidth eligibility of type non_assured\n");
2354 return BCM_ERR_PARM;
2355 }
2356 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2357 break;
2358 case 0: //AdditionalBW_None
2359 if (pir_bw == 0) {
2360 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
236116000 bytes/sec\n");
2362 return BCM_ERR_PARM;
2363 } else if (cir_bw == 0) {
2364 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2365for additional bandwidth eligibility of type None\n");
2366 return BCM_ERR_PARM;
2367 } else if (pir_bw > cir_bw) {
2368 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2369for additional bandwidth eligibility of type None\n");
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002370 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002371bandwidth in None eligibility\n", pir_bw);
2372 cir_bw = pir_bw;
2373 } else if (pir_bw < cir_bw) {
2374 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2375bandwidth (%d)\n", pir_bw, cir_bw);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002376 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002377bandwidth in None eligibility\n", pir_bw);
2378 cir_bw = pir_bw;
2379 }
2380 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2381 break;
2382 default:
2383 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002384 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002385 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2386 in a fine granularity. */
2387 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
2388 /* Fixed Bandwidth with no critical requirement of shaping */
2389 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, 0);
2390 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
2391 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, cir_bw);
2392 /* Maximum allocated bandwidth allowed for this alloc ID */
2393 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
2394 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002395 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002396 for skipped allocations during quiet window */
2397 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2398 /**< Allocation Profile index for CBR non-RT Bandwidth */
2399 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2400 /**< Allocation Profile index for CBR RT Bandwidth */
2401 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2402 /**< Alloc ID Weight used in case of Extended DBA mode */
2403 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2404 /**< Alloc ID Priority used in case of Extended DBA mode */
2405 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2406 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002407
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002408 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002409 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002410 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002411port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002412 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002413 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002414#ifndef SCALE_AND_PERF
Girish Gowdra96461052019-11-22 20:13:59 +05302415 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
2416 if (err) {
2417 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2418port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
2419 return err;
2420 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002421#endif
Girish Gowdra96461052019-11-22 20:13:59 +05302422
2423 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
2424port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
2425
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002426 }
2427
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002428 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002429}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002430
Girish Gowdra252f4972020-09-07 21:24:01 -07002431Status CreateTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002432 uint32_t intf_id = traffic_scheds->intf_id();
2433 uint32_t onu_id = traffic_scheds->onu_id();
2434 uint32_t uni_id = traffic_scheds->uni_id();
2435 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002436 std::string direction;
2437 unsigned int alloc_id;
Girish Gowdra252f4972020-09-07 21:24:01 -07002438 ::tech_profile::SchedulerConfig sched_config;
2439 ::tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002440 uint32_t priority;
2441 uint32_t weight;
Girish Gowdra252f4972020-09-07 21:24:01 -07002442 ::tech_profile::SchedulingPolicy sched_policy;
2443 ::tech_profile::TrafficShapingInfo traffic_shaping_info;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002444 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002445 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002446
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002447 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002448 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002449
2450 direction = GetDirection(traffic_sched.direction());
2451 if (direction.compare("direction-not-supported") == 0)
2452 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2453
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002454 alloc_id = traffic_sched.alloc_id();
2455 sched_config = traffic_sched.scheduler();
2456 additional_bw = sched_config.additional_bw();
2457 priority = sched_config.priority();
2458 weight = sched_config.weight();
2459 sched_policy = sched_config.sched_policy();
2460 traffic_shaping_info = traffic_sched.traffic_shaping_info();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002461 tech_profile_id = traffic_sched.tech_profile_id();
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002462 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002463 sched_policy, traffic_shaping_info, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002464 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002465 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002466 return bcm_to_grpc_err(err, "Failed to create scheduler");
2467 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002468 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002469 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002470}
Jonathan Davis70c21812018-07-19 15:32:10 -04002471
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002472bcmos_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 -04002473
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002474 bcmos_errno err;
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302475 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302476 bcmolt_status los_status;
Girish Gowdra96461052019-11-22 20:13:59 +05302477 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002478
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002479 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002480 bcmolt_itupon_alloc_cfg cfg;
2481 bcmolt_itupon_alloc_key key = { };
2482 key.pon_ni = intf_id;
2483 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302484 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002485
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002486 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002487 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2488 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002489 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2490 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002491 return err;
2492 }
Girish Gowdra96461052019-11-22 20:13:59 +05302493
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302494 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302495 if (err == BCM_ERR_OK) {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302496 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_OFF) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002497#ifndef SCALE_AND_PERF
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302498 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 +05302499 intf_id);
2500 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2501 if (err) {
2502 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2503 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
2504 return err;
2505 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002506#endif
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302507 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302508 else if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_ON) {
2509 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is enabled but LoS status is ON, not waiting for alloc cfg clear response\n",
2510 intf_id);
2511 }
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302512 else if (state == BCMOLT_INTERFACE_STATE_INACTIVE) {
2513 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is disabled, not waiting for alloc cfg clear response\n",
2514 intf_id);
2515 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302516 } else {
2517 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 +05302518 intf_id, bcmos_strerror(err));
Girish Gowdra96461052019-11-22 20:13:59 +05302519 return err;
2520 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002521 } else if (direction == downstream) {
2522 bcmolt_tm_sched_cfg cfg;
2523 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002524
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002525 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2526 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302527 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002528 } else {
2529 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2530 return BCM_ERR_OK;
2531 }
Girish Gowdra96461052019-11-22 20:13:59 +05302532
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002533 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2534 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2535 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002536 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002537intf_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 +00002538 return err;
2539 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002540 }
2541
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002542 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d, tech_profile_id %d\n",
2543 direction.c_str(), sched_id, intf_id, onu_id, tech_profile_id);
2544 free_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002545 return BCM_ERR_OK;
2546}
2547
Girish Gowdra252f4972020-09-07 21:24:01 -07002548Status RemoveTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002549 uint32_t intf_id = traffic_scheds->intf_id();
2550 uint32_t onu_id = traffic_scheds->onu_id();
2551 uint32_t uni_id = traffic_scheds->uni_id();
2552 std::string direction;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002553 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002554 bcmos_errno err;
2555
2556 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002557 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002558
2559 direction = GetDirection(traffic_sched.direction());
2560 if (direction.compare("direction-not-supported") == 0)
2561 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2562
2563 int alloc_id = traffic_sched.alloc_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002564 int tech_profile_id = traffic_sched.tech_profile_id();
2565 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002566 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002567 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002568 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2569 }
2570 }
2571 return Status::OK;
2572}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002573
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002574bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2575 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002576 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002577 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2578 bcmolt_tm_qmp_key tm_qmp_key;
2579 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002580
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002581 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2582 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002583 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed tm queue mapping profile count is 16.\n");
2584 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002585 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002586
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002587 tm_qmp_key.id = tm_qmp_id;
2588 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2589 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2590 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002591
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002592 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2593 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2594 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002595 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2596 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002597
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002598 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002599 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002600 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2601 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002602 return err;
2603 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002604
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002605 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2606 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002607 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002608}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002609
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002610bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2611 bcmos_errno err;
2612 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2613 bcmolt_tm_qmp_key tm_qmp_key;
2614 tm_qmp_key.id = tm_qmp_id;
2615
2616 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2617 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2618 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002619 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2620 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002621 return err;
2622 }
2623
2624 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2625 tm_qmp_key.id);
2626 return BCM_ERR_OK;
2627}
2628
2629bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2630 bcmos_errno err;
2631
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002632 /* Create default queues on the given PON/NNI scheduler */
2633 for (int queue_id = 0; queue_id < NUMBER_OF_DEFAULT_INTERFACE_QUEUES; queue_id++) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002634 bcmolt_tm_queue_cfg tm_queue_cfg;
2635 bcmolt_tm_queue_key tm_queue_key = {};
2636 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2637 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002638 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2639 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2640 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002641
2642 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2643 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2644 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2645
2646 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2647 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002648 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", \
2649 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 +00002650 return err;
2651 }
2652
2653 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2654 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2655 }
2656 return BCM_ERR_OK;
2657}
2658
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002659bcmos_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 +00002660 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 +00002661 bcmos_errno err;
2662 bcmolt_tm_queue_cfg cfg;
2663 bcmolt_tm_queue_key key = { };
2664 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 +00002665gemport_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 +00002666
2667 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002668 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002669
2670 if (priority > 7) {
2671 return BCM_ERR_RANGE;
2672 }
2673
2674 /* FIXME: The upstream queues have to be created once only.
2675 The upstream queues on the NNI scheduler are shared by all subscribers.
2676 When the first scheduler comes in, the queues get created, and are re-used by all others.
2677 Also, these queues should be present until the last subscriber exits the system.
2678 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2679
2680 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2681 for each GEM in TECH PROFILE */
2682 key.id = queue_id_list[priority];
2683
2684 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2685 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2686 key.id = 0;
2687 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2688 }
2689 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2690 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2691 }
2692 else {
2693 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2694 }
2695
2696 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2697
2698 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2699 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
2700
2701 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2702 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002703 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002704sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, tech_profile_id %d, err = %s\n", \
2705 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 +00002706 return err;
2707 }
2708
Girish Gowdra252f4972020-09-07 21:24:01 -07002709 if (direction.compare(upstream) == 0) {
2710 Status st = install_gem_port(access_intf_id, onu_id, gemport_id);
2711 if (st.error_code() != grpc::StatusCode::ALREADY_EXISTS && st.error_code() != grpc::StatusCode::OK) {
2712 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);
2713 return BCM_ERR_INTERNAL;
2714 }
2715 }
2716
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002717 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 +00002718intf_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 +00002719 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002720}
2721
Girish Gowdra252f4972020-09-07 21:24:01 -07002722Status CreateTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002723 uint32_t intf_id = traffic_queues->intf_id();
2724 uint32_t onu_id = traffic_queues->onu_id();
2725 uint32_t uni_id = traffic_queues->uni_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002726 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002727 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002728 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002729 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002730 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 +00002731
2732 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2733 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2734 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2735 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002736 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002737
2738 direction = GetDirection(traffic_queue.direction());
2739 if (direction.compare("direction-not-supported") == 0)
2740 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2741
2742 queues_priority_q[i] = traffic_queue.priority();
2743 queues_pbit_map[i] = traffic_queue.pbit_map();
2744 }
2745
2746 std::vector<uint32_t> tmq_map_profile(8, 0);
2747 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2748 queues_priority_q, COUNT_OF(queues_priority_q));
2749 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002750 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002751
2752 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2753 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002754 err = CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2755 if (err != BCM_ERR_OK) {
2756 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2757 return bcm_to_grpc_err(err, "Failed to create tm queue mapping profile");
2758 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002759 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2760 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2761 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2762 }
2763 }
2764
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002765 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002766 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002767
2768 direction = GetDirection(traffic_queue.direction());
2769 if (direction.compare("direction-not-supported") == 0)
2770 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2771
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002772 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 +00002773
Girish Gowdruf26cf882019-05-01 23:47:58 -07002774 // If the queue exists already, lets not return failure and break the loop.
2775 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002776 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002777 return bcm_to_grpc_err(err, "Failed to create queue");
2778 }
2779 }
2780 return Status::OK;
2781}
2782
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002783bcmos_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 +00002784 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 +00002785 bcmolt_tm_queue_cfg cfg;
2786 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002787 bcmos_errno err;
2788
2789 if (direction == downstream) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002790 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2791 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 +00002792 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002793 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002794 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 -08002795 return BCM_ERR_OK;
2796 }
2797 } else {
Girish Gowdra4fd30672020-11-09 17:23:06 -08002798 // Gemports are bi-directional (except in multicast case). We create the gem port when we create the
2799 // upstream queue (see CreateQueue function) and it makes sense to delete them when remove the upstream queues.
2800 // For multicast case we do not manage the install/remove of gem port in agent application. It is managed by BAL.
2801 // Moreover it also makes sense to remove when upstream queue is getting removed because the upstream queue MUST exist always.
2802 // It is possible that the downstream queues are not created for a subscriber (for ex: upstream EAPoL trap flow only exists
2803 // but no other flow, and in this case only upstream scheduler and queues exist. We do not have a scenario where only downstream
2804 // subscriber flows exist but no upstream )
2805 remove_gem_port(access_intf_id, gemport_id);
2806
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002807 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2808 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002809 return BCM_ERR_OK;
2810 }
2811
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002812 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2813 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2814 // Reset the queue id to 0 when using fixed queue.
2815 key.id = 0;
2816 }
2817 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2818 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2819 }
2820 else {
2821 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2822 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002823
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002824 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2825 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002826 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002827 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, queue_id %d, sched_id %d, \
2828tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n",
2829 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 -08002830 return err;
2831 }
2832
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002833 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2834intf_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 -08002835
2836 return BCM_ERR_OK;
2837}
2838
Girish Gowdra252f4972020-09-07 21:24:01 -07002839Status RemoveTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002840 uint32_t intf_id = traffic_queues->intf_id();
2841 uint32_t onu_id = traffic_queues->onu_id();
2842 uint32_t uni_id = traffic_queues->uni_id();
2843 uint32_t port_no = traffic_queues->port_no();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002844 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002845 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002846 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002847 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002848 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 +00002849
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002850 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002851 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002852
2853 direction = GetDirection(traffic_queue.direction());
2854 if (direction.compare("direction-not-supported") == 0)
2855 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2856
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002857 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 -08002858 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002859 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002860 return bcm_to_grpc_err(err, "Failed to remove queue");
2861 }
Jonathan Davis70c21812018-07-19 15:32:10 -04002862 }
2863
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002864 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 +00002865 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002866 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002867
2868 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
2869 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002870 err = RemoveTrafficQueueMappingProfile(tm_qmp_id);
2871 if (err != BCM_ERR_OK) {
2872 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2873 return bcm_to_grpc_err(err, "Failed to remove tm queue mapping profile");
2874 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002875 }
2876 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002877 clear_qos_type(intf_id, onu_id, uni_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04002878 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04002879}
Jason Huangbf45ffb2019-10-30 17:29:02 +08002880
Girish Gowdra252f4972020-09-07 21:24:01 -07002881Status PerformGroupOperation_(const ::openolt::Group *group_cfg) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002882
2883 bcmos_errno err;
2884 bcmolt_group_key key = {};
2885 bcmolt_group_cfg grp_cfg_obj;
2886 bcmolt_group_members_update grp_mem_upd;
2887 bcmolt_members_update_command grp_mem_upd_cmd;
2888 bcmolt_group_member_info member_info = {};
2889 bcmolt_group_member_info_list_u8 members = {};
2890 bcmolt_intf_ref interface_ref = {};
2891 bcmolt_egress_qos egress_qos = {};
2892 bcmolt_tm_sched_ref tm_sched_ref = {};
2893 bcmolt_action a_val = {};
2894
2895 uint32_t group_id = group_cfg->group_id();
2896
2897 OPENOLT_LOG(INFO, openolt_log_id, "PerformGroupOperation request received for Group %d\n", group_id);
2898
2899 if (group_id >= 0) {
2900 key.id = group_id;
2901 }
2902 else {
2903 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
2904 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
2905 }
2906
2907 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2908 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
2909
2910 OPENOLT_LOG(INFO, openolt_log_id, "Checking if Group %d exists...\n",group_id);
2911
2912 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
2913 if (err != BCM_ERR_OK) {
2914 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
2915 return bcm_to_grpc_err(err, "Error in querying group");
2916 }
2917
2918 members.len = group_cfg->members_size();
2919
2920 // IMPORTANT: A member cannot be added to a group if the group type is not determined.
2921 // Group type is determined after a flow is assigned to it.
2922 // Therefore, a group must be created first, then a flow (with multicast type) must be assigned to it.
2923 // Only then we can add members to the group.
2924
2925 // if group does not exist, create it and return.
2926 if (grp_cfg_obj.data.state == BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
2927
2928 if (members.len != 0) {
2929 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);
2930 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Non-empty member list given for non-existent group");
2931 } else {
2932
2933 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2934 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, cookie, key.id);
2935
2936 /* Setting group actions and action parameters, if any.
2937 Only remove_outer_tag and translate_inner_tag actions and i_vid action parameter
2938 are supported for multicast groups in BAL 3.1.
2939 */
2940 const ::openolt::Action& action = group_cfg->action();
2941 const ::openolt::ActionCmd &cmd = action.cmd();
2942
2943 bcmolt_action_cmd_id cmd_bmask = BCMOLT_ACTION_CMD_ID_NONE;
2944 if (cmd.remove_outer_tag()) {
2945 OPENOLT_LOG(INFO, openolt_log_id, "Action remove_outer_tag applied to Group %d.\n", group_id);
2946 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
2947 }
2948
2949 if (cmd.translate_inner_tag()) {
2950 OPENOLT_LOG(INFO, openolt_log_id, "Action translate_inner_tag applied to Group %d.\n", group_id);
2951 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG);
2952 }
2953
2954 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, cmd_bmask);
2955
2956 if (action.i_vid()) {
2957 OPENOLT_LOG(INFO, openolt_log_id, "Setting action parameter i_vid=%d for Group %d.\n", action.i_vid(), group_id);
2958 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
2959 }
2960
2961 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, action, a_val);
2962
2963 // Create group
2964 err = bcmolt_cfg_set(dev_id, &(grp_cfg_obj.hdr));
2965
2966 if (BCM_ERR_OK != err) {
2967 BCM_LOG(ERROR, openolt_log_id, "Failed to create Group %d, err = %s (%d)\n", key.id, bcmos_strerror(err), err);
2968 return bcm_to_grpc_err(err, "Error in creating group");
2969 }
2970
2971 BCM_LOG(INFO, openolt_log_id, "Group %d has been created and configured with empty member list.\n", key.id);
2972 return Status::OK;
2973 }
2974 }
2975
2976 // The group already exists. Continue configuring it according to the update member command.
2977
2978 OPENOLT_LOG(INFO, openolt_log_id, "Configuring existing Group %d.\n",group_id);
2979
2980 // MEMBER LIST CONSTRUCTION
2981 // Note that members.len can be 0 here. if the group already exists and the command is SET then sending
2982 // empty list to the group is a legit operation and this actually empties the member list.
2983 members.arr = (bcmolt_group_member_info*)bcmos_calloc((members.len)*sizeof(bcmolt_group_member_info));
2984
2985 if (!members.arr) {
2986 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to allocate memory for group member list.\n");
2987 return grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "Memory exhausted during member list creation");
2988 }
2989
2990 /* SET GROUP MEMBERS UPDATE COMMAND */
Girish Gowdra252f4972020-09-07 21:24:01 -07002991 ::openolt::Group::GroupMembersCommand command = group_cfg->command();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002992 switch(command) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002993 case ::openolt::Group::SET_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002994 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_SET;
2995 OPENOLT_LOG(INFO, openolt_log_id, "Setting %d members for Group %d.\n", members.len, group_id);
2996 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07002997 case ::openolt::Group::ADD_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002998 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_ADD;
2999 OPENOLT_LOG(INFO, openolt_log_id, "Adding %d members to Group %d.\n", members.len, group_id);
3000 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003001 case ::openolt::Group::REMOVE_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003002 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_REMOVE;
3003 OPENOLT_LOG(INFO, openolt_log_id, "Removing %d members from Group %d.\n", members.len, group_id);
3004 break;
3005 default :
3006 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid value %d for group member command.\n", command);
3007 bcmos_free(members.arr);
3008 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group member command");
3009 }
3010
3011 // SET MEMBERS LIST
3012 for (int i = 0; i < members.len; i++) {
3013
Girish Gowdra252f4972020-09-07 21:24:01 -07003014 if (command == ::openolt::Group::REMOVE_MEMBERS) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003015 OPENOLT_LOG(INFO, openolt_log_id, "Removing group member %d from group %d\n",i,key.id);
3016 } else {
3017 OPENOLT_LOG(INFO, openolt_log_id, "Adding group member %d to group %d\n",i,key.id);
3018 }
3019
Girish Gowdra252f4972020-09-07 21:24:01 -07003020 ::openolt::GroupMember *member = (::openolt::GroupMember *) &group_cfg->members()[i];
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003021
3022 // Set member interface type
Girish Gowdra252f4972020-09-07 21:24:01 -07003023 ::openolt::GroupMember::InterfaceType if_type = member->interface_type();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003024 switch(if_type){
Girish Gowdra252f4972020-09-07 21:24:01 -07003025 case ::openolt::GroupMember::PON :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003026 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_PON);
3027 OPENOLT_LOG(INFO, openolt_log_id, "Interface type PON is assigned to GroupMember %d\n",i);
3028 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003029 case ::openolt::GroupMember::EPON_1G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003030 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_1_G);
3031 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_1G is assigned to GroupMember %d\n",i);
3032 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003033 case ::openolt::GroupMember::EPON_10G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003034 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_10_G);
3035 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_10G is assigned to GroupMember %d\n",i);
3036 break;
3037 default :
3038 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid interface type value %d for GroupMember %d.\n",if_type,i);
3039 bcmos_free(members.arr);
3040 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface type for a group member");
3041 }
3042
3043 // Set member interface id
3044 if (member->interface_id() >= 0) {
3045 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_id, member->interface_id());
3046 OPENOLT_LOG(INFO, openolt_log_id, "Interface %d is assigned to GroupMember %d\n", member->interface_id(), i);
3047 } else {
3048 bcmos_free(members.arr);
3049 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface id for a group member");
3050 }
3051
3052 // Set member interface_ref
3053 BCMOLT_FIELD_SET(&member_info, group_member_info, intf, interface_ref);
3054
3055 // Set member gem_port_id. This must be a multicast gemport.
3056 if (member->gem_port_id() >= 0) {
3057 BCMOLT_FIELD_SET(&member_info, group_member_info, svc_port_id, member->gem_port_id());
3058 OPENOLT_LOG(INFO, openolt_log_id, "GEM Port %d is assigned to GroupMember %d\n", member->gem_port_id(), i);
3059 } else {
3060 bcmos_free(members.arr);
3061 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid gem port id for a group member");
3062 }
3063
3064 // Set member scheduler id and queue_id
3065 uint32_t tm_sched_id = get_default_tm_sched_id(member->interface_id(), downstream);
3066 OPENOLT_LOG(INFO, openolt_log_id, "Scheduler %d is assigned to GroupMember %d\n", tm_sched_id, i);
3067 BCMOLT_FIELD_SET(&tm_sched_ref, tm_sched_ref, id, tm_sched_id);
3068 BCMOLT_FIELD_SET(&egress_qos, egress_qos, tm_sched, tm_sched_ref);
3069
3070 // We assume that all multicast traffic destined to a PON port is using the same fixed queue.
3071 uint32_t tm_queue_id;
3072 if (member->priority() >= 0 && member->priority() < NUMBER_OF_DEFAULT_INTERFACE_QUEUES) {
3073 tm_queue_id = queue_id_list[member->priority()];
3074 OPENOLT_LOG(INFO, openolt_log_id, "Queue %d is assigned to GroupMember %d\n", tm_queue_id, i);
3075 BCMOLT_FIELD_SET(&egress_qos, egress_qos, type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
3076 BCMOLT_FIELD_SET(&egress_qos.u.fixed_queue, egress_qos_fixed_queue, queue_id, tm_queue_id);
3077 } else {
3078 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid fixed queue priority/ID %d for GroupMember %d\n", member->priority(), i);
3079 bcmos_free(members.arr);
3080 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid queue priority for a group member");
3081 }
3082
3083 BCMOLT_FIELD_SET(&member_info, group_member_info, egress_qos, egress_qos);
3084 BCMOLT_ARRAY_ELEM_SET(&(members), i, member_info);
3085 }
3086
3087 BCMOLT_OPER_INIT(&grp_mem_upd, group, members_update, key);
3088 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.members, members);
3089 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.command, grp_mem_upd_cmd);
3090
3091 err = bcmolt_oper_submit(dev_id, &(grp_mem_upd.hdr));
3092 bcmos_free(members.arr);
3093
3094 if (BCM_ERR_OK != err) {
3095 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);
3096 return bcm_to_grpc_err(err, "Failed to submit members update operation for the group");
3097 }
3098
3099 OPENOLT_LOG(INFO, openolt_log_id, "Successfully submitted members update operation for Group %d\n", key.id);
3100
3101 return Status::OK;
3102}
Burak Gurdageb4ca2e2020-06-15 07:48:26 +00003103
3104Status DeleteGroup_(uint32_t group_id) {
3105
3106 bcmos_errno err = BCM_ERR_OK;
3107 bcmolt_group_cfg grp_cfg_obj;
3108 bcmolt_group_key key = {};
3109
3110
3111 OPENOLT_LOG(INFO, openolt_log_id, "Delete request received for group %d\n", group_id);
3112
3113 if (group_id >= 0) {
3114 key.id = group_id;
3115 } else {
3116 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
3117 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
3118 }
3119
3120 /* init the BAL INIT API */
3121 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3122
3123 OPENOLT_LOG(DEBUG, openolt_log_id, "Checking if group %d exists...\n",group_id);
3124
3125 // CONFIGURE GROUP MEMBERS
3126 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
3127 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
3128
3129 if (err != BCM_ERR_OK) {
3130 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
3131 return bcm_to_grpc_err(err, "Error in querying group");
3132 }
3133
3134 if (grp_cfg_obj.data.state != BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
3135 OPENOLT_LOG(DEBUG, openolt_log_id, "Group %d exists. Will be deleted.\n",group_id);
3136 err = bcmolt_cfg_clear(dev_id, &(grp_cfg_obj.hdr));
3137 if (err != BCM_ERR_OK) {
3138 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d cannot be deleted err = %s (%d).\n", group_id, bcmos_strerror(err), err);
3139 return bcm_to_grpc_err(err, "Failed to delete group");;
3140 }
3141 } else {
3142 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d does not exist.\n", group_id);
3143 return Status(grpc::StatusCode::NOT_FOUND, "Group not found");
3144 }
3145
3146 OPENOLT_LOG(INFO, openolt_log_id, "Group %d has been deleted successfully.\n", group_id);
3147 return Status::OK;
Jason Huang1d9cfce2020-05-20 22:58:47 +08003148}
3149
Girish Gowdra252f4972020-09-07 21:24:01 -07003150Status GetLogicalOnuDistanceZero_(uint32_t intf_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003151 bcmos_errno err = BCM_ERR_OK;
3152 uint32_t mld = 0;
3153 double LD0;
3154
3155 err = getOnuMaxLogicalDistance(intf_id, &mld);
3156 if (err != BCM_ERR_OK) {
3157 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3158 }
3159
3160 LD0 = LOGICAL_DISTANCE(mld*1000, MINIMUM_ONU_RESPONSE_RANGING_TIME, ONU_BIT_TRANSMISSION_DELAY);
3161 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance zero is %f, (PON %d)\n", LD0, intf_id);
3162 response->set_intf_id(intf_id);
3163 response->set_logical_onu_distance_zero(LD0);
3164
3165 return Status::OK;
3166}
3167
Girish Gowdra252f4972020-09-07 21:24:01 -07003168Status GetLogicalOnuDistance_(uint32_t intf_id, uint32_t onu_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003169 bcmos_errno err = BCM_ERR_OK;
3170 bcmolt_itu_onu_params itu = {};
3171 bcmolt_onu_cfg onu_cfg;
3172 bcmolt_onu_key onu_key = {};
3173 uint32_t mld = 0;
3174 double LDi;
3175
3176 onu_key.pon_ni = intf_id;
3177 onu_key.onu_id = onu_id;
3178
3179 err = getOnuMaxLogicalDistance(intf_id, &mld);
3180 if (err != BCM_ERR_OK) {
3181 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3182 }
3183
3184 /* Initialize the API struct. */
3185 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
3186 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
3187 BCMOLT_FIELD_SET_PRESENT(&itu, itu_onu_params, ranging_time);
3188 BCMOLT_FIELD_SET(&onu_cfg.data, onu_cfg_data, itu, itu);
3189 #ifdef TEST_MODE
3190 // It is impossible to mock the setting of onu_cfg.data.onu_state because
3191 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
3192 // set the onu_cfg.data.onu_state. So a new stub function is created and address
3193 // of onu_cfg is passed. This is one-of case where we need to add test specific
3194 // code in production code.
3195 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
3196 #else
3197 /* Call API function. */
3198 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
3199 #endif
3200 if (err != BCM_ERR_OK) {
3201 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);
3202 return bcm_to_grpc_err(err, "Failed to retrieve ONU ranging time");
3203 }
3204
3205 if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_ACTIVE) {
3206 OPENOLT_LOG(ERROR, openolt_log_id, "ONU is not yet activated (PON %d, ONU id %d)\n", intf_id, onu_id);
3207 return bcm_to_grpc_err(BCM_ERR_PARM, "ONU is not yet activated\n");
3208 }
3209
3210 LDi = LOGICAL_DISTANCE(mld*1000, onu_cfg.data.itu.ranging_time, ONU_BIT_TRANSMISSION_DELAY);
3211 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance is %f, (PON %d, ONU id %d)\n", LDi, intf_id, onu_id);
3212 response->set_intf_id(intf_id);
3213 response->set_onu_id(onu_id);
3214 response->set_logical_onu_distance(LDi);
3215
3216 return Status::OK;
3217}
Burak Gurdag74e3ab82020-12-17 13:35:06 +00003218
3219Status GetOnuStatistics_(uint32_t intf_id, uint32_t onu_id, openolt::OnuStatistics* onu_stats) {
3220 bcmos_errno err;
3221
3222 err = get_onu_statistics((bcmolt_interface_id)intf_id, (bcmolt_onu_id)onu_id, onu_stats);
3223
3224 if (err != BCM_ERR_OK) {
3225 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));
3226 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of ONU statistics failed");
3227 }
3228
3229 OPENOLT_LOG(INFO, openolt_log_id, "retrieved ONU statistics for PON ID = %d, ONU ID = %d\n", (int)intf_id, (int)onu_id);
3230 return Status::OK;
3231}
3232
3233Status GetGemPortStatistics_(uint32_t intf_id, uint32_t gemport_id, openolt::GemPortStatistics* gemport_stats) {
3234 bcmos_errno err;
3235
3236 err = get_gemport_statistics((bcmolt_interface_id)intf_id, (bcmolt_gem_port_id)gemport_id, gemport_stats);
3237
3238 if (err != BCM_ERR_OK) {
3239 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));
3240 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of GEMPORT statistics failed");
3241 }
3242
3243 OPENOLT_LOG(INFO, openolt_log_id, "retrieved GEMPORT statistics for PON ID = %d, GEMPORT ID = %d\n", (int)intf_id, (int)gemport_id);
3244 return Status::OK;
3245}