blob: a4e902f3fd49bb1a755a40b0c0a3231caf0f0be0 [file] [log] [blame]
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001/*
Girish Gowdraa707e7c2019-11-07 11:36:13 +05302 * Copyright 2018-present Open Networking Foundation
Shad Ansarib7b0ced2018-05-11 21:53:32 +00003
Girish Gowdraa707e7c2019-11-07 11:36:13 +05304 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
Shad Ansarib7b0ced2018-05-11 21:53:32 +00007
Girish Gowdraa707e7c2019-11-07 11:36:13 +05308 * http://www.apache.org/licenses/LICENSE-2.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00009
Girish Gowdraa707e7c2019-11-07 11:36:13 +053010 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +000016
17#include <iostream>
18#include <memory>
19#include <string>
20
21#include "Queue.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000022#include <sstream>
Nicolas Palpacuer9c352082018-08-14 16:37:14 -040023#include <chrono>
24#include <thread>
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080025#include <bitset>
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000026#include <inttypes.h>
Jason Huangbf45ffb2019-10-30 17:29:02 +080027#include <unistd.h>
Jason Huang09b73ea2020-01-08 17:52:05 +080028#include <sys/socket.h>
29#include <netinet/in.h>
30#include <arpa/inet.h>
Shad Ansarib7b0ced2018-05-11 21:53:32 +000031
Craig Lutgen88a22ad2018-10-04 12:30:46 -050032#include "device.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000033#include "core.h"
Girish Gowdraddf9a162020-01-27 12:56:27 +053034#include "core_data.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000035#include "indications.h"
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -040036#include "stats_collection.h"
Nicolas Palpacuer73222e02018-07-16 12:20:26 -040037#include "error_format.h"
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -040038#include "state.h"
Girish Gowdraddf9a162020-01-27 12:56:27 +053039#include "core_utils.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000040
41extern "C"
42{
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000043#include <bcmolt_api.h>
44#include <bcmolt_host_api.h>
45#include <bcmolt_api_model_supporting_enums.h>
46
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000047#include <bcmolt_api_conn_mgr.h>
48//CLI header files
49#include <bcmcli_session.h>
50#include <bcmcli.h>
51#include <bcm_api_cli.h>
52
53#include <bcmos_common.h>
54#include <bcm_config.h>
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -040055// FIXME : dependency problem
56// #include <bcm_common_gpon.h>
Nicolas Palpacuer967438f2018-09-07 14:41:54 -040057// #include <bcm_dev_log_task.h>
Shad Ansarib7b0ced2018-05-11 21:53:32 +000058}
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000059
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000060static std::string intf_technologies[MAX_SUPPORTED_PON];
Craig Lutgen88a22ad2018-10-04 12:30:46 -050061static const std::string UNKNOWN_TECH("unknown");
Craig Lutgenb2601f02018-10-23 13:04:31 -050062static const std::string MIXED_TECH("mixed");
63static std::string board_technology(UNKNOWN_TECH);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000064static std::string chip_family(UNKNOWN_TECH);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000065static std::string firmware_version = "Openolt.2019.07.01";
Nicolas Palpacuerdff96792018-09-06 14:59:32 -040066
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080067static bcmos_errno CreateSched(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
Girish Gowdra252f4972020-09-07 21:24:01 -070068 uint32_t port_no, uint32_t alloc_id, ::tech_profile::AdditionalBW additional_bw, uint32_t weight, \
69 uint32_t priority, ::tech_profile::SchedulingPolicy sched_policy,
70 ::tech_profile::TrafficShapingInfo traffic_shaping_info, uint32_t tech_profile_id);
Burak Gurdag2f2618c2020-04-23 13:20:30 +000071static bcmos_errno RemoveSched(int intf_id, int onu_id, int uni_id, int alloc_id, std::string direction, int tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080072static bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +000073 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id, uint32_t tech_profile_id);
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -050074static bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +000075 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id, uint32_t tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000076static bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction);
77static bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction);
78
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000079inline const char *get_flow_acton_command(uint32_t command) {
80 char actions[200] = { };
81 char *s_actions_ptr = actions;
82 if (command & BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG) strcat(s_actions_ptr, "ADD_OUTER_TAG|");
83 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG) strcat(s_actions_ptr, "REMOVE_OUTER_TAG|");
84 if (command & BCMOLT_ACTION_CMD_ID_XLATE_OUTER_TAG) strcat(s_actions_ptr, "TRANSLATE_OUTER_TAG|");
85 if (command & BCMOLT_ACTION_CMD_ID_ADD_INNER_TAG) strcat(s_actions_ptr, "ADD_INNTER_TAG|");
86 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_INNER_TAG) strcat(s_actions_ptr, "REMOVE_INNER_TAG|");
87 if (command & BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG) strcat(s_actions_ptr, "TRANSLATE_INNER_TAG|");
88 if (command & BCMOLT_ACTION_CMD_ID_REMARK_OUTER_PBITS) strcat(s_actions_ptr, "REMOVE_OUTER_PBITS|");
89 if (command & BCMOLT_ACTION_CMD_ID_REMARK_INNER_PBITS) strcat(s_actions_ptr, "REMAKE_INNER_PBITS|");
90 return s_actions_ptr;
91}
92
kesavandc1f2db92020-08-31 15:32:06 +053093bcmolt_stat_alarm_config set_stat_alarm_config(const config::OnuItuPonAlarm* request) {
Jason Huang5d9ab1a2020-04-15 16:53:49 +080094 bcmolt_stat_alarm_config alarm_cfg = {};
95 bcmolt_stat_alarm_trigger_config trigger_obj = {};
96 bcmolt_stat_alarm_soak_config soak_obj = {};
97
98 switch (request->alarm_reporting_condition()) {
kesavandc1f2db92020-08-31 15:32:06 +053099 case config::OnuItuPonAlarm::RATE_THRESHOLD:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800100 trigger_obj.type = BCMOLT_STAT_CONDITION_TYPE_RATE_THRESHOLD;
101 BCMOLT_FIELD_SET(&trigger_obj.u.rate_threshold, stat_alarm_trigger_config_rate_threshold,
102 rising, request->rate_threshold_config().rate_threshold_rising());
103 BCMOLT_FIELD_SET(&trigger_obj.u.rate_threshold, stat_alarm_trigger_config_rate_threshold,
104 falling, request->rate_threshold_config().rate_threshold_falling());
105 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, active_soak_time,
106 request->rate_threshold_config().soak_time().active_soak_time());
107 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, clear_soak_time,
108 request->rate_threshold_config().soak_time().clear_soak_time());
109 break;
kesavandc1f2db92020-08-31 15:32:06 +0530110 case config::OnuItuPonAlarm::RATE_RANGE:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800111 trigger_obj.type = BCMOLT_STAT_CONDITION_TYPE_RATE_RANGE;
112 BCMOLT_FIELD_SET(&trigger_obj.u.rate_range, stat_alarm_trigger_config_rate_range, upper,
113 request->rate_range_config().rate_range_upper());
114 BCMOLT_FIELD_SET(&trigger_obj.u.rate_range, stat_alarm_trigger_config_rate_range, lower,
115 request->rate_range_config().rate_range_lower());
116 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, active_soak_time,
117 request->rate_range_config().soak_time().active_soak_time());
118 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, clear_soak_time,
119 request->rate_range_config().soak_time().clear_soak_time());
120 break;
kesavandc1f2db92020-08-31 15:32:06 +0530121 case config::OnuItuPonAlarm::VALUE_THRESHOLD:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800122 trigger_obj.type = BCMOLT_STAT_CONDITION_TYPE_VALUE_THRESHOLD;
123 BCMOLT_FIELD_SET(&trigger_obj.u.value_threshold, stat_alarm_trigger_config_value_threshold,
124 limit, request->value_threshold_config().threshold_limit());
125 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, active_soak_time,
126 request->value_threshold_config().soak_time().active_soak_time());
127 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, clear_soak_time,
128 request->value_threshold_config().soak_time().clear_soak_time());
129 break;
130 default:
131 OPENOLT_LOG(ERROR, openolt_log_id, "unsupported alarm reporting condition = %u\n", request->alarm_reporting_condition());
132 // For now just log the error and not return error. We can handle this scenario in the future.
133 break;
134 }
135
136 BCMOLT_FIELD_SET(&alarm_cfg, stat_alarm_config, trigger, trigger_obj);
137 BCMOLT_FIELD_SET(&alarm_cfg, stat_alarm_config, soak, soak_obj);
138
139 return alarm_cfg;
140}
141
kesavandc1f2db92020-08-31 15:32:06 +0530142Status OnuItuPonAlarmSet_(const config::OnuItuPonAlarm* request) {
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800143 bcmos_errno err;
144 bcmolt_onu_itu_pon_stats_cfg stat_cfg; /* declare main API struct */
145 bcmolt_onu_key key = {}; /* declare key */
146 bcmolt_stat_alarm_config errors_cfg = {};
147
148 key.pon_ni = request->pon_ni();
149 key.onu_id = request->onu_id();
150
151 /* Initialize the API struct. */
152 BCMOLT_STAT_CFG_INIT(&stat_cfg, onu, itu_pon_stats, key);
153
154 /*
155 1. BCMOLT_STAT_CONDITION_TYPE_NONE = 0, The alarm is disabled.
156 2. BCMOLT_STAT_CONDITION_TYPE_RATE_THRESHOLD = 1, The alarm is triggered if the stats delta value between samples
157 crosses the configured threshold boundary.
158 rising: The alarm is raised if the stats delta value per second becomes greater than this threshold level.
159 falling: The alarm is cleared if the stats delta value per second becomes less than this threshold level.
160 3. BCMOLT_STAT_CONDITION_TYPE_RATE_RANGE = 2, The alarm is triggered if the stats delta value between samples
161 deviates from the configured range.
162 upper: The alarm is raised if the stats delta value per second becomes greater than this upper level.
163 lower: The alarm is raised if the stats delta value per second becomes less than this lower level.
164 4. BCMOLT_STAT_CONDITION_TYPE_VALUE_THRESHOLD = 3, The alarm is raised if the stats sample value becomes greater
165 than this level. The alarm is cleared when the host read the stats.
166 limit: The alarm is raised if the stats sample value becomes greater than this level.
167 The alarm is cleared when the host clears the stats.
168
169 active_soak_time: If the alarm condition is raised and stays in the raised state for at least this amount
170 of time (unit=seconds), the alarm indication is sent to the host.
171 The OLT delays the alarm indication no less than this delay period.
172 It can be delayed more than this period because of the statistics sampling interval.
173 clear_soak_time: After the alarm is raised, if it is cleared and stays in the cleared state for at least
174 this amount of time (unit=seconds), the alarm indication is sent to the host.
175 The OLT delays the alarm indication no less than this delay period. It can be delayed more
176 than this period because of the statistics sampling interval.
177 */
178
179 errors_cfg = set_stat_alarm_config(request);
180
181 switch (request->alarm_id()) {
kesavandc1f2db92020-08-31 15:32:06 +0530182 case config::OnuItuPonAlarm_AlarmID::OnuItuPonAlarm_AlarmID_RDI_ERRORS:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800183 //set the rdi_errors alarm
184 BCMOLT_FIELD_SET(&stat_cfg.data, onu_itu_pon_stats_cfg_data, rdi_errors, errors_cfg);
185 break;
186 default:
187 OPENOLT_LOG(ERROR, openolt_log_id, "could not find the alarm id %d\n", request->alarm_id());
188 return bcm_to_grpc_err(BCM_ERR_PARM, "the alarm id is wrong");
189 }
190
191 err = bcmolt_stat_cfg_set(dev_id, &stat_cfg.hdr);
192 if (err != BCM_ERR_OK) {
193 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to set onu itu pon stats, alarm id %d, pon_ni %d, onu_id %d, err = %s\n",
194 request->alarm_id(), key.pon_ni, key.onu_id, bcmos_strerror(err));
195 return bcm_to_grpc_err(err, "set Onu ITU PON stats alarm faild");
196 } else {
197 OPENOLT_LOG(INFO, openolt_log_id, "set onu itu pon stats alarm %d successfully, pon_ni %d, onu_id %d\n",
198 request->alarm_id(), key.pon_ni, key.onu_id);
199 }
200
201 return Status::OK;
202}
203
Girish Gowdra252f4972020-09-07 21:24:01 -0700204Status GetDeviceInfo_(::openolt::DeviceInfo* device_info) {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500205 device_info->set_vendor(VENDOR_ID);
206 device_info->set_model(MODEL_ID);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400207 device_info->set_hardware_version("");
208 device_info->set_firmware_version(firmware_version);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500209 device_info->set_technology(board_technology);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500210 device_info->set_pon_ports(num_of_pon_ports);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500211
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800212 char serial_number[OPENOLT_FIELD_LEN];
213 memset(serial_number, '\0', OPENOLT_FIELD_LEN);
214 openolt_read_sysinfo("Serial Number", serial_number);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000215 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device serial number %s\n", serial_number);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800216 device_info->set_device_serial_number(serial_number);
Burak Gurdag30db4822021-03-10 21:30:01 +0000217 device_info->set_previously_connected(state.previously_connected());
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800218
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700219 char device_id[OPENOLT_FIELD_LEN];
220 memset(device_id, '\0', OPENOLT_FIELD_LEN);
Humera Kouser6143c9e2020-06-17 22:37:31 +0530221
222 if (grpc_server_interface_name != NULL) {
223 if (get_intf_mac(grpc_server_interface_name, device_id, sizeof(device_id)) != NULL)
224 {
225 OPENOLT_LOG(INFO, openolt_log_id, "Fetched mac address %s of an interface %s\n", device_id, grpc_server_interface_name);
226 }
227 else
228 {
229 OPENOLT_LOG(ERROR, openolt_log_id, "Mac address of an interface %s is NULL\n", grpc_server_interface_name);
230 }
231 }
232 else
233 {
234 openolt_read_sysinfo("MAC", device_id);
235 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device mac address %s\n", device_id);
236 }
237
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700238 device_info->set_device_id(device_id);
239
Craig Lutgenb2601f02018-10-23 13:04:31 -0500240 // Legacy, device-wide ranges. To be deprecated when adapter
241 // is upgraded to support per-interface ranges
Girish Gowdra252f4972020-09-07 21:24:01 -0700242 device_info->set_onu_id_start(ONU_ID_START);
243 device_info->set_onu_id_end(ONU_ID_END);
244 device_info->set_alloc_id_start(ALLOC_ID_START);
245 device_info->set_alloc_id_end(ALLOC_ID_END);
246 device_info->set_gemport_id_start(GEM_PORT_ID_START);
247 device_info->set_gemport_id_end(GEM_PORT_ID_END);
248 device_info->set_flow_id_start(FLOW_ID_START);
249 device_info->set_flow_id_end(FLOW_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500250
Girish Gowdra252f4972020-09-07 21:24:01 -0700251 std::map<std::string, ::openolt::DeviceInfo::DeviceResourceRanges*> ranges;
Craig Lutgenb2601f02018-10-23 13:04:31 -0500252 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
253 std::string intf_technology = intf_technologies[intf_id];
Girish Gowdra252f4972020-09-07 21:24:01 -0700254 ::openolt::DeviceInfo::DeviceResourceRanges *range = ranges[intf_technology];
Craig Lutgenb2601f02018-10-23 13:04:31 -0500255 if(range == nullptr) {
256 range = device_info->add_ranges();
257 ranges[intf_technology] = range;
258 range->set_technology(intf_technology);
259
Girish Gowdra252f4972020-09-07 21:24:01 -0700260 ::openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
Craig Lutgenb2601f02018-10-23 13:04:31 -0500261
Girish Gowdra252f4972020-09-07 21:24:01 -0700262 pool = range->add_pools();
263 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
264 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
265 pool->set_start(ONU_ID_START);
266 pool->set_end(ONU_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500267
Girish Gowdra252f4972020-09-07 21:24:01 -0700268 pool = range->add_pools();
269 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
270 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
271 pool->set_start(ALLOC_ID_START);
272 pool->set_end(ALLOC_ID_START);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500273
Girish Gowdra252f4972020-09-07 21:24:01 -0700274 pool = range->add_pools();
275 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
276 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
277 pool->set_start(GEM_PORT_ID_START);
278 pool->set_end(GEM_PORT_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500279
Girish Gowdra252f4972020-09-07 21:24:01 -0700280 pool = range->add_pools();
281 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
282 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
283 pool->set_start(FLOW_ID_START);
284 pool->set_end(FLOW_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500285 }
286
287 range->add_intf_ids(intf_id);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500288 }
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400289
290 // FIXME: Once dependency problem is fixed
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500291 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400292 // device_info->set_onu_id_end(XGPON_NUM_OF_ONUS - 1);
293 // device_info->set_alloc_id_start(1024);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500294 // device_info->set_alloc_id_end(XGPON_NUM_OF_ALLOC_IDS * num_of_pon_ports ? - 1);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400295 // device_info->set_gemport_id_start(XGPON_MIN_BASE_SERVICE_PORT_ID);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500296 // device_info->set_gemport_id_end(XGPON_NUM_OF_GEM_PORT_IDS_PER_PON * num_of_pon_ports ? - 1);
297 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400298
299 return Status::OK;
300}
301
Shad Ansari627b5782018-08-13 22:49:32 +0000302Status Enable_(int argc, char *argv[]) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000303 bcmos_errno err;
304 bcmolt_host_init_parms init_parms = {};
305 init_parms.transport.type = BCM_HOST_API_CONN_LOCAL;
306 unsigned int failed_enable_device_cnt = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000307
Shad Ansariedef2132018-08-10 22:14:50 +0000308 if (!state.is_activated()) {
Shad Ansari627b5782018-08-13 22:49:32 +0000309
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500310 vendor_init();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000311 /* Initialize host subsystem */
312 err = bcmolt_host_init(&init_parms);
313 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500314 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to init OLT, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000315 return bcm_to_grpc_err(err, "Failed to init OLT");
316 }
317
318 bcmcli_session_parm mon_session_parm;
319 /* Create CLI session */
320 memset(&mon_session_parm, 0, sizeof(mon_session_parm));
321 mon_session_parm.get_prompt = openolt_cli_get_prompt_cb;
322 mon_session_parm.access_right = BCMCLI_ACCESS_ADMIN;
323 bcmos_errno rc = bcmcli_session_open(&mon_session_parm, &current_session);
324 BUG_ON(rc != BCM_ERR_OK);
325
326 /* API CLI */
327 bcm_openolt_api_cli_init(NULL, current_session);
328
329 /* Add quit command */
330 BCMCLI_MAKE_CMD_NOPARM(NULL, "quit", "Quit", bcm_cli_quit);
331
332 err = bcmolt_apiend_cli_init();
333 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500334 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to add apiend init, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000335 return bcm_to_grpc_err(err, "Failed to add apiend init");
336 }
337
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800338 bcmos_fastlock_init(&data_lock, 0);
Girish Gowdra252f4972020-09-07 21:24:01 -0700339 bcmos_fastlock_init(&acl_id_bitset_lock, 0);
340 bcmos_fastlock_init(&tm_sched_bitset_lock, 0);
341 bcmos_fastlock_init(&tm_qmp_bitset_lock, 0);
342 bcmos_fastlock_init(&flow_id_bitset_lock, 0);
343 bcmos_fastlock_init(&voltha_flow_to_device_flow_lock, 0);
Girish Gowdra96461052019-11-22 20:13:59 +0530344 bcmos_fastlock_init(&alloc_cfg_wait_lock, 0);
Girish Gowdra7a79dae2020-02-10 18:22:11 +0530345 bcmos_fastlock_init(&onu_deactivate_wait_lock, 0);
Girish Gowdra1935e6a2020-10-31 21:48:22 -0700346 bcmos_fastlock_init(&acl_packet_trap_handler_lock, 0);
347
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000348 OPENOLT_LOG(INFO, openolt_log_id, "Enable OLT - %s-%s\n", VENDOR_ID, MODEL_ID);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600349
Jason Huangbf45ffb2019-10-30 17:29:02 +0800350 //check BCM daemon is connected or not
351 Status status = check_connection();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000352 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800353 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000354 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800355 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000356 Status status = SubscribeIndication();
357 if (!status.ok()) {
358 OPENOLT_LOG(ERROR, openolt_log_id, "SubscribeIndication failed - %s : %s\n",
359 grpc_status_code_to_string(status.error_code()).c_str(),
360 status.error_message().c_str());
361 return status;
362 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800363
364 //check BAL state in initial stage
365 status = check_bal_ready();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000366 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800367 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000368 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800369 }
370
371 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000372 bcmos_errno err;
373 bcmolt_odid dev;
374 OPENOLT_LOG(INFO, openolt_log_id, "Enabling PON %d Devices ... \n", BCM_MAX_DEVS_PER_LINE_CARD);
375 for (dev = 0; dev < BCM_MAX_DEVS_PER_LINE_CARD; dev++) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400376 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000377 bcmolt_device_key dev_key = { };
378 dev_key.device_id = dev;
379 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
380 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
381 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
Jason Huangbf45ffb2019-10-30 17:29:02 +0800382 if (err == BCM_ERR_NOT_CONNECTED) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000383 bcmolt_device_key key = {.device_id = dev};
384 bcmolt_device_connect oper;
385 BCMOLT_OPER_INIT(&oper, device, connect, key);
386 if (MODEL_ID == "asfvolt16") {
387 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
388 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_XGS__2_X);
389 } else if (MODEL_ID == "asgvolt64") {
390 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
391 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
392 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
393 }
394 err = bcmolt_oper_submit(dev_id, &oper.hdr);
395 if (err) {
396 failed_enable_device_cnt ++;
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500397 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 +0000398 if (failed_enable_device_cnt == BCM_MAX_DEVS_PER_LINE_CARD) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500399 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 +0000400 return Status(grpc::StatusCode::INTERNAL, "Failed to activate all PON ports");
401 }
402 }
403 bcmos_usleep(200000);
404 }
405 else {
406 OPENOLT_LOG(WARNING, openolt_log_id, "PON deivce %d already connected\n", dev);
407 state.activate();
408 }
409 }
410 init_stats();
Shad Ansari627b5782018-08-13 22:49:32 +0000411 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000412 }
Shad Ansariedef2132018-08-10 22:14:50 +0000413
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000414 /* Start CLI */
415 OPENOLT_LOG(INFO, def_log_id, "Starting CLI\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400416 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000417 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400418}
419
420Status Disable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400421 //In the earlier implementation Disabling olt is done by disabling the NNI port associated with that.
422 //In inband scenario instead of using management interface to establish connection with adapter ,NNI interface will be used.
423 //Disabling NNI port on olt disable causes connection loss between adapter and agent.
424 //To overcome this disable is implemented by disabling all the PON ports
425 //associated with the device so as to support both in-band
426 //and out of band scenarios.
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400427
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400428 Status status;
429 int failedCount = 0;
Girish Gowdrae1db2952021-05-04 00:16:54 -0700430 OPENOLT_LOG(INFO, openolt_log_id, "Received disable OLT\n");
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400431 for (int i = 0; i < NumPonIf_(); i++) {
432 status = DisablePonIf_(i);
433 if (!status.ok()) {
434 failedCount+=1;
435 BCM_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", i);
436 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400437 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400438 if (failedCount == 0) {
439 state.deactivate();
Girish Gowdra252f4972020-09-07 21:24:01 -0700440 ::openolt::Indication ind;
441 ::openolt::OltIndication* olt_ind = new ::openolt::OltIndication;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400442 olt_ind->set_oper_state("down");
443 ind.set_allocated_olt_ind(olt_ind);
444 BCM_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
445 oltIndQ.push(ind);
446 return Status::OK;
447 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000448 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400449 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to disable olt ,all the PON ports are still in enabled state");
450 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400451
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400452 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 -0400453}
454
455Status Reenable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400456 Status status;
457 int failedCount = 0;
458 for (int i = 0; i < NumPonIf_(); i++) {
459 status = EnablePonIf_(i);
460 if (!status.ok()) {
461 failedCount+=1;
462 BCM_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", i);
463 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400464 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000465 if (failedCount == 0) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400466 state.activate();
Girish Gowdra252f4972020-09-07 21:24:01 -0700467 ::openolt::Indication ind;
468 ::openolt::OltIndication* olt_ind = new ::openolt::OltIndication;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400469 olt_ind->set_oper_state("up");
470 ind.set_allocated_olt_ind(olt_ind);
471 BCM_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
472 oltIndQ.push(ind);
473 return Status::OK;
474 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000475 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400476 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to re-enable olt ,all the PON ports are still in disabled state");
477 }
478 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 +0000479}
480
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000481inline uint64_t get_flow_status(uint16_t flow_id, uint16_t flow_type, uint16_t data_id) {
482 bcmos_errno err;
483 bcmolt_flow_key flow_key;
484 bcmolt_flow_cfg flow_cfg;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400485
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000486 flow_key.flow_id = flow_id;
487 flow_key.flow_type = (bcmolt_flow_type)flow_type;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400488
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000489 BCMOLT_CFG_INIT(&flow_cfg, flow, flow_key);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400490
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000491 switch (data_id) {
492 case ONU_ID: //onu_id
493 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, onu_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500494 #ifdef TEST_MODE
495 // It is impossible to mock the setting of flow_cfg.data.state because
496 // the actual bcmolt_cfg_get passes the address of flow_cfg.hdr and we cannot
497 // set the flow_cfg.data. So a new stub function is created and address
498 // of flow_cfg is passed. This is one-of case where we need to add test specific
499 // code in production code.
500 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
501 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000502 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500503 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000504 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500505 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get onu_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000506 return err;
507 }
508 return flow_cfg.data.onu_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400509 case FLOW_TYPE:
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500510 #ifdef TEST_MODE
511 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
512 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000513 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500514 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000515 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500516 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get flow_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000517 return err;
518 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400519 return flow_cfg.key.flow_type;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000520 case SVC_PORT_ID: //svc_port_id
521 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, svc_port_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500522 #ifdef TEST_MODE
523 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
524 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000525 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500526 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000527 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500528 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 +0000529 return err;
530 }
531 return flow_cfg.data.svc_port_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400532 case PRIORITY:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000533 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, priority);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500534 #ifdef TEST_MODE
535 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
536 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000537 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500538 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000539 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500540 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get priority, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000541 return err;
542 }
543 return flow_cfg.data.priority;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400544 case COOKIE: //cookie
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000545 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, cookie);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500546 #ifdef TEST_MODE
547 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
548 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000549 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500550 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000551 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500552 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get cookie, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000553 return err;
554 }
555 return flow_cfg.data.cookie;
556 case INGRESS_INTF_TYPE: //ingress intf_type
557 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500558 #ifdef TEST_MODE
559 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
560 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000561 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500562 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000563 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500564 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 +0000565 return err;
566 }
567 return flow_cfg.data.ingress_intf.intf_type;
568 case EGRESS_INTF_TYPE: //egress intf_type
569 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500570 #ifdef TEST_MODE
571 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
572 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000573 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500574 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000575 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500576 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 +0000577 return err;
578 }
579 return flow_cfg.data.egress_intf.intf_type;
580 case INGRESS_INTF_ID: //ingress intf_id
581 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500582 #ifdef TEST_MODE
583 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
584 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000585 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500586 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000587 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500588 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 +0000589 return err;
590 }
591 return flow_cfg.data.ingress_intf.intf_id;
592 case EGRESS_INTF_ID: //egress intf_id
593 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500594 #ifdef TEST_MODE
595 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
596 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000597 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500598 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000599 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500600 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 +0000601 return err;
602 }
603 return flow_cfg.data.egress_intf.intf_id;
604 case CLASSIFIER_O_VID:
605 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500606 #ifdef TEST_MODE
607 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
608 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000609 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500610 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000611 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500612 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 +0000613 return err;
614 }
615 return flow_cfg.data.classifier.o_vid;
616 case CLASSIFIER_O_PBITS:
617 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500618 #ifdef TEST_MODE
619 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
620 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000621 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500622 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000623 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500624 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 +0000625 return err;
626 }
627 return flow_cfg.data.classifier.o_pbits;
628 case CLASSIFIER_I_VID:
629 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500630 #ifdef TEST_MODE
631 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
632 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000633 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500634 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000635 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500636 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 +0000637 return err;
638 }
639 return flow_cfg.data.classifier.i_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400640 case CLASSIFIER_I_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000641 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500642 #ifdef TEST_MODE
643 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
644 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000645 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500646 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000647 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500648 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 +0000649 return err;
650 }
651 return flow_cfg.data.classifier.i_pbits;
652 case CLASSIFIER_ETHER_TYPE:
653 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500654 #ifdef TEST_MODE
655 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
656 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000657 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500658 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000659 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500660 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 +0000661 return err;
662 }
663 return flow_cfg.data.classifier.ether_type;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400664 case CLASSIFIER_IP_PROTO:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000665 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500666 #ifdef TEST_MODE
667 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
668 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000669 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500670 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000671 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500672 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 +0000673 return err;
674 }
675 return flow_cfg.data.classifier.ip_proto;
676 case CLASSIFIER_SRC_PORT:
677 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500678 #ifdef TEST_MODE
679 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
680 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000681 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500682 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000683 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500684 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 +0000685 return err;
686 }
687 return flow_cfg.data.classifier.src_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400688 case CLASSIFIER_DST_PORT:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000689 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500690 #ifdef TEST_MODE
691 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
692 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000693 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500694 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000695 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500696 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 +0000697 return err;
698 }
699 return flow_cfg.data.classifier.dst_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400700 case CLASSIFIER_PKT_TAG_TYPE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000701 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500702 #ifdef TEST_MODE
703 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
704 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000705 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500706 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000707 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500708 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 +0000709 return err;
710 }
711 return flow_cfg.data.classifier.pkt_tag_type;
712 case EGRESS_QOS_TYPE:
713 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500714 #ifdef TEST_MODE
715 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
716 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000717 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500718 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000719 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500720 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 +0000721 return err;
722 }
723 return flow_cfg.data.egress_qos.type;
724 case EGRESS_QOS_QUEUE_ID:
725 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500726 #ifdef TEST_MODE
727 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
728 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000729 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500730 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000731 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500732 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 +0000733 return err;
734 }
735 switch (flow_cfg.data.egress_qos.type) {
736 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE:
737 return flow_cfg.data.egress_qos.u.fixed_queue.queue_id;
738 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE:
739 return flow_cfg.data.egress_qos.u.tc_to_queue.tc_to_queue_id;
740 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC:
741 return flow_cfg.data.egress_qos.u.pbit_to_tc.tc_to_queue_id;
742 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE:
743 return flow_cfg.data.egress_qos.u.priority_to_queue.tm_q_set_id;
744 case BCMOLT_EGRESS_QOS_TYPE_NONE:
745 default:
746 return -1;
747 }
748 case EGRESS_QOS_TM_SCHED_ID:
749 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500750 #ifdef TEST_MODE
751 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
752 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000753 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500754 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000755 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500756 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 +0000757 return err;
758 }
759 return flow_cfg.data.egress_qos.tm_sched.id;
760 case ACTION_CMDS_BITMASK:
761 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500762 #ifdef TEST_MODE
763 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
764 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000765 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500766 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000767 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500768 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 +0000769 return err;
770 }
771 return flow_cfg.data.action.cmds_bitmask;
772 case ACTION_O_VID:
773 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500774 #ifdef TEST_MODE
775 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
776 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000777 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500778 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000779 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500780 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 +0000781 return err;
782 }
783 return flow_cfg.data.action.o_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400784 case ACTION_O_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000785 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500786 #ifdef TEST_MODE
787 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
788 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000789 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500790 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000791 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500792 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 +0000793 return err;
794 }
795 return flow_cfg.data.action.o_pbits;
796 case ACTION_I_VID:
797 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500798 #ifdef TEST_MODE
799 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
800 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000801 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500802 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000803 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500804 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 +0000805 return err;
806 }
807 return flow_cfg.data.action.i_vid;
808 case ACTION_I_PBITS:
809 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500810 #ifdef TEST_MODE
811 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
812 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000813 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500814 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000815 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500816 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 +0000817 return err;
818 }
819 return flow_cfg.data.action.i_pbits;
820 case STATE:
821 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, state);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500822 #ifdef TEST_MODE
823 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
824 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000825 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500826 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000827 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500828 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get state, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000829 return err;
830 }
831 return flow_cfg.data.state;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000832 case GROUP_ID:
833 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, group_id);
834 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
835 if (err) {
836 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get group_id, err = %s\n",bcmos_strerror(err));
837 return err;
838 }
839 return flow_cfg.data.group_id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000840 default:
841 return BCM_ERR_INTERNAL;
842 }
843
844 return err;
845}
846
847Status EnablePonIf_(uint32_t intf_id) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400848 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000849 bcmolt_pon_interface_cfg interface_obj;
850 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
851 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
852 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530853 bcmolt_status los_status;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000854
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530855 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000856 if (err == BCM_ERR_OK) {
857 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800858 OPENOLT_LOG(WARNING, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000859 return Status::OK;
860 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400861 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000862 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
863 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
864 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
865 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.interval, 5000);
866 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.onu_post_discovery_mode,
Girish Gowdra24297032020-03-23 12:32:37 -0700867 BCMOLT_ONU_POST_DISCOVERY_MODE_NONE);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000868 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.los, true);
869 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.onu_alarms, true);
870 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.tiwi, true);
871 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.ack_timeout, true);
872 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.sfi, true);
873 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.loki, true);
Burak Gurdag5e587792020-05-06 14:58:02 +0000874
875 // On GPON, power level mode is not set to its default value (i.e. 0) as documented in Broadcom documentation.
876 // Instead, it is set to 2 which means -6 dbM attenuation. Therefore, we explicitly set it to the default value below.
877 if (board_technology == "GPON") {
878 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.pls_maximum_allocation_size, BCMOLT_PON_POWER_LEVEL_PLS_MAXIMUM_ALLOCATION_SIZE_DEFAULT);
879 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.mode, BCMOLT_PON_POWER_LEVEL_MODE_DEFAULT);
880 }
881
kesavandc1f2db92020-08-31 15:32:06 +0530882 //Enable AES Encryption
883 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.key_exchange, BCMOLT_CONTROL_STATE_ENABLE);
884 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.authentication, BCMOLT_CONTROL_STATE_ENABLE);
885 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.fail_due_to_authentication_failure, BCMOLT_CONTROL_STATE_ENABLE);
886
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000887 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
888 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
889
890 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
891 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500892 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 +0000893 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
894 }
895 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
896 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500897 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 +0000898 return bcm_to_grpc_err(err, "Failed to enable PON interface");
899 }
900 else {
901 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
902 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
903 CreateDefaultSched(intf_id, downstream);
904 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400905 }
906
907 return Status::OK;
908}
909
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500910Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000911 bcmos_errno err;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400912 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000913 bcmolt_device_key dev_key = { };
914 bcmolt_olt_cfg olt_cfg = { };
915 bcmolt_olt_key olt_key = { };
916 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
917 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500918
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000919 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
920 topo.topology_maps.arr = &topo_map[0];
921 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
922 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
923 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400924 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000925 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400926 #ifdef TEST_MODE
927 // It is impossible to mock the setting of olt_cfg.data.bal_state because
928 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
929 // set the olt_cfg.data.topology. So a new stub function is created and address
930 // of olt_cfg is passed. This is one-of case where we need to test add specific
931 // code in production code.
932 err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
933 #else
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000934 err = bcmolt_cfg_get_mult_retry(dev_id, &olt_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400935 #endif
936 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500937 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 +0000938 return bcm_to_grpc_err(err, "cfg: Failed to query OLT topology");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500939 }
940
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000941 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
942 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500943
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400944 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
945 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000946 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500947
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000948 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
949 num_of_nni_ports,
950 num_of_pon_ports,
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400951 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500952
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000953 uint32_t num_failed_cfg_gets = 0;
Jason Huang09b73ea2020-01-08 17:52:05 +0800954 static std::string openolt_version = firmware_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000955 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
956 dev_key.device_id = devid;
957 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
958 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
959 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
960 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000961 err = bcmolt_cfg_get_mult_retry(dev_id, &dev_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400962 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500963 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 +0000964 num_failed_cfg_gets++;
965 continue;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000966 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500967
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000968 std::string bal_version;
969 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
970 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
971 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
Jason Huang09b73ea2020-01-08 17:52:05 +0800972 firmware_version = "BAL." + bal_version + "__" + openolt_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000973
974 switch(dev_cfg.data.system_mode) {
975 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
976 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
977 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
978 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
979 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
980 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
981 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
982 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
983 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
984 case 20: board_technology = MIXED_TECH; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,MIXED_TECH); break;
985 }
986
987 switch(dev_cfg.data.chip_family) {
Jason Huang09b73ea2020-01-08 17:52:05 +0800988 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X: chip_family = "Maple"; break;
989 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X: chip_family = "Aspen"; break;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000990 }
991
Jason Huang09b73ea2020-01-08 17:52:05 +0800992 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s, family: %s, board_technology: %s\n",
993 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 +0000994
995 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500996 }
997
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000998 /* 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 +0000999 only the devices that retured success*/
1000 if (num_failed_cfg_gets == BCM_MAX_DEVS_PER_LINE_CARD) {
1001 OPENOLT_LOG(ERROR, openolt_log_id, "device: Query of all the devices failed\n");
1002 return bcm_to_grpc_err(err, "device: All devices failed query");
1003 }
1004
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001005 return Status::OK;
1006}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001007
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001008Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001009 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001010 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
1011 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
1012 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001013
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001014 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001015 if (err == BCM_ERR_OK) {
1016 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001017 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001018 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1019 CreateDefaultSched(intf_id, upstream);
1020 CreateDefaultQueue(intf_id, upstream);
1021 return Status::OK;
1022 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1023 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
1024 return Status::OK;
1025 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001026 }
1027
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001028 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
1029 if (set_state) {
1030 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1031 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1032 } else {
1033 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1034 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1035 }
1036 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
1037 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001038 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err = %s\n",
1039 (set_state)?"enable":"disable", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001040 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
1041 }
1042 else {
1043 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
1044 if (set_state) {
1045 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1046 CreateDefaultSched(intf_id, upstream);
1047 CreateDefaultQueue(intf_id, upstream);
1048 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001049 }
1050
1051 return Status::OK;
1052}
1053
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001054Status DisablePonIf_(uint32_t intf_id) {
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001055 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001056 bcmolt_pon_interface_cfg interface_obj;
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001057 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1058 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001059
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001060 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
Girish Gowdrae1db2952021-05-04 00:16:54 -07001061 BCMOLT_MSG_FIELD_GET(&interface_obj, state);
1062
1063 err = bcmolt_cfg_get(dev_id, &interface_obj.hdr);
1064 if (err != BCM_ERR_OK) {
1065 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch pon port status, PON interface %d, err %d err_text=%s \n", intf_id, err, interface_obj.hdr.hdr.err_text);
1066 return bcm_to_grpc_err(err, "Failed to fetch pon port state");
1067 }
1068 if (interface_obj.data.state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1069 OPENOLT_LOG(INFO, openolt_log_id, "PON Interface already inactive, PON interface %d\n", intf_id);
1070 return Status::OK;
1071 }
1072
1073 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001074 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1075 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_DISABLE);
1076
1077 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1078 if (err != BCM_ERR_OK) {
1079 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable discovery of onu, PON interface %d, err %d\n", intf_id, err);
1080 return bcm_to_grpc_err(err, "Failed to disable discovery of onu");
1081 }
1082
1083 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1084 operation, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1085
1086 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1087 if (err != BCM_ERR_OK) {
1088 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 -04001089 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001090 }
1091
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001092 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled PON interface: %d\n", intf_id);
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001093 return Status::OK;
1094}
1095
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001096Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
kesavandc1f2db92020-08-31 15:32:06 +05301097 const char *vendor_id, const char *vendor_specific, uint32_t pir, bool omcc_encryption_mode) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001098 bcmos_errno err = BCM_ERR_OK;
1099 bcmolt_onu_cfg onu_cfg;
1100 bcmolt_onu_key onu_key;
1101 bcmolt_serial_number serial_number; /**< ONU serial number */
1102 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001103
Girish Gowdra24297032020-03-23 12:32:37 -07001104 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1105 bcmolt_onu_state onu_state;
1106
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001107 onu_key.onu_id = onu_id;
1108 onu_key.pon_ni = intf_id;
1109 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1110 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Girish Gowdra24297032020-03-23 12:32:37 -07001111#ifdef TEST_MODE
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001112 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1113 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1114 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1115 // of onu_cfg is passed. This is one-of case where we need to add test specific
1116 // code in production code.
1117 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Girish Gowdra24297032020-03-23 12:32:37 -07001118#else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001119 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Girish Gowdra24297032020-03-23 12:32:37 -07001120#endif
1121 OPENOLT_LOG(INFO, openolt_log_id, "Activate ONU : old state = %d, current state = %d\n",
1122 onu_cfg.data.onu_old_state, onu_cfg.data.onu_state);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001123 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001124 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) {
1125 OPENOLT_LOG(INFO, openolt_log_id, "ONU is already in ACTIVE state, \
1126not processing this request for pon_intf=%d onu_id=%d\n", intf_id, onu_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001127 return Status::OK;
Girish Gowdra24297032020-03-23 12:32:37 -07001128 } else if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_NOT_CONFIGURED &&
1129 onu_cfg.data.onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1130 // We need the ONU to be in NOT_CONFIGURED or INACTIVE state to further process the request
1131 OPENOLT_LOG(ERROR, openolt_log_id, "ONU in an invalid state to process the request, \
1132state=%d pon_intf=%d onu_id=%d\n", onu_cfg.data.onu_state, intf_id, onu_id);
1133 return bcm_to_grpc_err(err, "Failed to activate ONU, invalid ONU state");
1134 }
1135 } else {
1136 // This should never happen. BAL GET should succeed for non-existant ONUs too. The state of such ONUs will be NOT_CONFIGURED
1137 OPENOLT_LOG(ERROR, openolt_log_id, "ONU state query failed pon_intf=%d onu_id=%d\n", intf_id, onu_id);
1138 return bcm_to_grpc_err(err, "onu get failed");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001139 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001140
Girish Gowdra24297032020-03-23 12:32:37 -07001141 // If the ONU is not configured at all we need to first configure it
1142 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_NOT_CONFIGURED) {
1143 OPENOLT_LOG(INFO, openolt_log_id, "Configuring ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001144vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Girish Gowdra24297032020-03-23 12:32:37 -07001145 vendor_specific_to_str(vendor_specific).c_str(), pir);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001146
Girish Gowdra24297032020-03-23 12:32:37 -07001147 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1148 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1149 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1150 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1151 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1152 /*set burst and data profiles to fec disabled*/
1153 if (board_technology == "XGS-PON") {
1154 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1155 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1156 } else if (board_technology == "GPON") {
1157 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1158 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1159 }
1160 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1161 if (err != BCM_ERR_OK) {
1162 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to configure ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
1163 return bcm_to_grpc_err(err, "Failed to configure ONU");
1164 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001165 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001166
Burak Gurdaga0523592021-02-24 15:17:47 +00001167// TODO: MOVE THIS TO A NEW METHOD
kesavandc1f2db92020-08-31 15:32:06 +05301168 if (omcc_encryption_mode == true) {
1169 // set the encryption mode for omci port id
1170 bcmolt_itupon_gem_cfg gem_cfg;
1171 bcmolt_itupon_gem_key key = {};
1172 bcmolt_gem_port_configuration configuration = {};
1173 key.pon_ni = intf_id;
1174 key.gem_port_id = onu_id;
1175 bcmolt_control_state encryption_mode;
1176 encryption_mode = BCMOLT_CONTROL_STATE_ENABLE;
1177 BCMOLT_CFG_INIT(&gem_cfg, itupon_gem, key);
1178 BCMOLT_FIELD_SET(&gem_cfg.data, itupon_gem_cfg_data, encryption_mode, encryption_mode);
1179 err = bcmolt_cfg_set(dev_id, &gem_cfg.hdr);
1180 if(err != BCM_ERR_OK) {
Burak Gurdaga0523592021-02-24 15:17:47 +00001181 OPENOLT_LOG(ERROR, openolt_log_id, "failed to configure omci gem_port encryption mode = %d\n", onu_id);
kesavandc1f2db92020-08-31 15:32:06 +05301182 return bcm_to_grpc_err(err, "Access_Control set ITU PON OMCI Gem port failed");
1183 }
1184 }
Girish Gowdra24297032020-03-23 12:32:37 -07001185 // Now that the ONU is configured, move the ONU to ACTIVE state
1186 memset(&onu_cfg, 0, sizeof(bcmolt_onu_cfg));
1187 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1188 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1189 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
1190 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
1191 onu_state, BCMOLT_ONU_OPERATION_ACTIVE);
1192 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001193 if (err != BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001194 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 +00001195 return bcm_to_grpc_err(err, "Failed to activate ONU");
1196 }
Girish Gowdra24297032020-03-23 12:32:37 -07001197 // ONU will eventually get activated after we have submitted the operation request. The adapter will receive an asynchronous
1198 // ONU_ACTIVATION_COMPLETED_INDICATION
1199
1200 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 +00001201
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001202 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001203}
1204
Jonathan Davis70c21812018-07-19 15:32:10 -04001205Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1206 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001207 bcmos_errno err = BCM_ERR_OK;
1208 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1209 bcmolt_onu_cfg onu_cfg;
1210 bcmolt_onu_key onu_key; /**< Object key. */
1211 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001212
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001213 onu_key.onu_id = onu_id;
1214 onu_key.pon_ni = intf_id;
1215 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1216 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001217 #ifdef TEST_MODE
1218 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1219 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1220 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1221 // of onu_cfg is passed. This is one-of case where we need to add test specific
1222 // code in production code.
1223 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001224 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001225 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001226 #endif
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301227 onu_state = onu_cfg.data.onu_state;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001228 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001229 switch (onu_state) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001230 case BCMOLT_ONU_STATE_ACTIVE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001231 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001232 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001233 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1234 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1235 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001236 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 +00001237 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1238 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301239 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 +00001240 break;
1241 }
Jonathan Davis70c21812018-07-19 15:32:10 -04001242 }
1243
1244 return Status::OK;
1245}
1246
1247Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001248 const char *vendor_id, const char *vendor_specific) {
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301249 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301250 bcmolt_onu_state onu_state;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001251
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001252 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 -05001253 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1254
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001255 // Need to deactivate before removing it (BAL rules)
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001256 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301257
1258 err = get_onu_status((bcmolt_interface)intf_id, onu_id, &onu_state);
1259 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001260 if (onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1261 OPENOLT_LOG(INFO, openolt_log_id, "waiting for onu deactivate complete response: intf_id=%d, onu_id=%d\n",
1262 intf_id, onu_id);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301263 err = wait_for_onu_deactivate_complete(intf_id, onu_id);
1264 if (err) {
1265 OPENOLT_LOG(ERROR, openolt_log_id, "failed to delete onu intf_id %d, onu_id %d\n",
1266 intf_id, onu_id);
1267 return bcm_to_grpc_err(err, "Failed to delete ONU");
1268 }
1269 }
Girish Gowdra24297032020-03-23 12:32:37 -07001270 else {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301271 OPENOLT_LOG(INFO, openolt_log_id, "Onu is Inactive, onu_id: %d, not waiting for onu deactivate complete response\n",
1272 intf_id);
1273 }
1274 }
1275 else {
1276 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch Onu status, onu_id = %d, intf_id = %d, err = %s\n",
1277 onu_id, intf_id, bcmos_strerror(err));
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301278 return bcm_to_grpc_err(err, "Failed to delete ONU");
1279 }
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001280
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001281 bcmolt_onu_cfg cfg_obj;
1282 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001283
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001284 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 -04001285 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001286
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001287 key.onu_id = onu_id;
1288 key.pon_ni = intf_id;
1289 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001290
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301291 err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001292 if (err != BCM_ERR_OK)
1293 {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001294 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 -04001295 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1296 }
1297
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301298 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 +00001299 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001300}
1301
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001302#define MAX_CHAR_LENGTH 20
1303#define MAX_OMCI_MSG_LENGTH 44
1304Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001305 bcmolt_bin_str buf = {};
1306 bcmolt_onu_cpu_packets omci_cpu_packets;
1307 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001308
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001309 key.pon_ni = intf_id;
1310 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001311
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001312 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1313 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1314 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001315
1316 // ???
1317 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1318 buf.len = MAX_OMCI_MSG_LENGTH;
1319 } else {
1320 buf.len = pkt.size()/2;
1321 }
1322
1323 /* Send the OMCI packet using the BAL remote proxy API */
1324 uint16_t idx1 = 0;
1325 uint16_t idx2 = 0;
1326 uint8_t arraySend[buf.len];
1327 char str1[MAX_CHAR_LENGTH];
1328 char str2[MAX_CHAR_LENGTH];
1329 memset(&arraySend, 0, buf.len);
1330
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001331 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1332 sprintf(str1,"%c", pkt[idx1]);
1333 sprintf(str2,"%c", pkt[++idx1]);
1334 strcat(str1,str2);
1335 arraySend[idx2] = strtol(str1, NULL, 16);
1336 }
1337
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001338 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1339 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001340
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001341 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1342 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1343 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001344
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001345 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001346 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001347 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 +00001348 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001349 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001350 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 -05001351 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001352 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001353 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001354
1355 return Status::OK;
1356}
1357
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001358Status 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 +00001359 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1360 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1361 bcmolt_bin_str buf = {};
1362 bcmolt_gem_port_id gem_port_id_array[1];
1363 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001364
Craig Lutgen967a1d02018-11-27 10:41:51 -06001365 if (port_no > 0) {
1366 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001367 if (gemport_id == 0) {
1368 bcmos_fastlock_lock(&data_lock);
1369 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1370 // Pick any flow that is mapped with the same port_no.
1371 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1372 if (it != port_to_flows.end() && !it->second.empty()) {
1373 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1374 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1375 if (fit != flowid_to_gemport.end()) {
1376 found = true;
1377 gemport_id = fit->second;
1378 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001379 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001380 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001381
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001382 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001383 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 -08001384 onu_id, port_no, intf_id);
1385 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1386 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001387 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 -08001388 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001389 }
1390
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001391 gem_port_id_array[0] = gemport_id;
1392 gem_port_list.len = 1;
1393 gem_port_list.arr = gem_port_id_array;
1394 buf.len = pkt.size();
1395 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1396 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1397
1398 /* init the API struct */
1399 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1400 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1401 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1402 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1403 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1404
1405 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1406 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1407
1408 /* call API */
1409 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001410 }
1411 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001412 //TODO: Port No is 0, it is coming sender requirement.
1413 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1414 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001415 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001416 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001417
1418 return Status::OK;
1419}
1420
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001421Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001422 bcmolt_flow_key key = {}; /* declare key */
1423 bcmolt_bin_str buffer = {};
1424 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001425
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001426 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
Girish Gowdra252f4972020-09-07 21:24:01 -07001427 bcmolt_flow_id flow_id = INVALID_FLOW_ID;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001428
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001429 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1430 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1431 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1432 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1433 key.flow_id = flow_id;
1434 else {
Jason Huang09b73ea2020-01-08 17:52:05 +08001435 if (flow_id_counters) {
1436 std::map<flow_pair, int>::iterator it;
1437 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1438 int flow_index = it->first.first;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001439 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1440 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1441 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1442 key.flow_id = flow_index;
1443 break;
1444 }
1445 }
1446 }
1447 else {
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001448 OPENOLT_LOG(ERROR, openolt_log_id, "no flow id found for uplink packetout\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001449 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1450 }
1451 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001452
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001453 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001454
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001455 /* Initialize the API struct. */
1456 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001457
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001458 buffer.len = pkt.size();
1459 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1460 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1461 if (buffer.arr == NULL) {
1462 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1463 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1464 }
1465 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1466
1467 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1468 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001469 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 -05001470 return bcm_to_grpc_err(BCM_ERR_SYSCALL_ERR, "Error sending packets via nni port");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001471 } else {
1472 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1473 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001474
1475 return Status::OK;
1476}
Girish Gowdra252f4972020-09-07 21:24:01 -07001477
Burak Gurdaga0523592021-02-24 15:17:47 +00001478bool get_aes_flag_for_gem_port(const google::protobuf::Map<unsigned int, bool> &gemport_to_aes, uint32_t gemport_id) {
1479 bool aes_flag = false;
1480 for (google::protobuf::Map<unsigned int, bool>::const_iterator it=gemport_to_aes.begin(); it!=gemport_to_aes.end(); it++) {
1481 if (it->first == gemport_id) {
1482 aes_flag = it->second;
1483 break;
1484 }
1485 }
1486 return aes_flag;
1487}
1488
Girish Gowdra252f4972020-09-07 21:24:01 -07001489Status FlowAddWrapper_(const ::openolt::Flow* request) {
1490
1491 int32_t access_intf_id = request->access_intf_id();
1492 int32_t onu_id = request->onu_id();
1493 int32_t uni_id = request->uni_id();
1494 uint32_t port_no = request->port_no();
1495 uint64_t voltha_flow_id = request->flow_id();
1496 uint64_t symmetric_voltha_flow_id = request->symmetric_flow_id();
1497 const std::string flow_type = request->flow_type();
1498 int32_t alloc_id = request->alloc_id();
1499 int32_t network_intf_id = request->network_intf_id();
1500 int32_t gemport_id = request->gemport_id();
1501 const ::openolt::Classifier& classifier = request->classifier();
1502 const ::openolt::Action& action = request->action();
1503 int32_t priority = request->priority();
1504 uint64_t cookie = request->cookie();
1505 int32_t group_id = request->group_id();
1506 uint32_t tech_profile_id = request->tech_profile_id();
1507 bool replicate_flow = request->replicate_flow();
1508 const google::protobuf::Map<unsigned int, unsigned int> &pbit_to_gemport = request->pbit_to_gemport();
Burak Gurdaga0523592021-02-24 15:17:47 +00001509 const google::protobuf::Map<unsigned int, bool> &gemport_to_aes = request->gemport_to_aes();
Girish Gowdra252f4972020-09-07 21:24:01 -07001510 uint16_t flow_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001511 bool enable_encryption;
Girish Gowdra252f4972020-09-07 21:24:01 -07001512
1513 // The intf_id variable defaults to access(PON) interface ID.
1514 // For trap-from-nni flow where access interface ID is not valid , change it to NNI interface ID
1515 // This intf_id identifies the pool from which we get the flow_id
1516 uint32_t intf_id = access_intf_id;
1517 if (onu_id < 1) {
1518 onu_id = 1;
1519 }
1520 if (access_intf_id < 0) {
1521 intf_id = network_intf_id;
1522 }
1523
1524 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)
1525 // This is the case of voltha_flow_id (not symmetric_voltha_flow_id)
1526 if (is_voltha_flow_installed(voltha_flow_id)) {
1527 OPENOLT_LOG(INFO, openolt_log_id, "voltha_flow_id=%lu, already installed\n", voltha_flow_id);
1528 return ::Status(grpc::StatusCode::ALREADY_EXISTS, "voltha-flow-already-installed");
1529 }
1530
Girish Gowdra252f4972020-09-07 21:24:01 -07001531 // This is the case of symmetric_voltha_flow_id
1532 // If symmetric_voltha_flow_id is available and valid in the Flow message,
1533 // check if it is installed, and use the corresponding device_flow_id
1534 if (symmetric_voltha_flow_id > 0 && is_voltha_flow_installed(symmetric_voltha_flow_id)) { // symmetric flow found
1535 OPENOLT_LOG(INFO, openolt_log_id, "symmetric flow and the symmetric flow is installed\n");
1536 const device_flow_params *dev_fl_symm_params;
1537 dev_fl_symm_params = get_device_flow_params(symmetric_voltha_flow_id);
1538 if (dev_fl_symm_params == NULL) {
1539 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)
1540 return ::Status(grpc::StatusCode::INTERNAL, "symmetric-flow-details-not-found");
1541 }
1542
1543 if (!replicate_flow) { // No flow replication
1544 flow_id = dev_fl_symm_params[0].flow_id;
1545 gemport_id = dev_fl_symm_params[0].gemport_id; // overwrite the gemport with symmetric flow gemport
1546 // Should be same as what is coming in this request.
Burak Gurdaga0523592021-02-24 15:17:47 +00001547 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001548 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1549 cl.set_o_pbits(dev_fl_symm_params[0].pbit);
1550 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1551 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001552 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001553 if (st.error_code() == grpc::StatusCode::OK) {
1554 device_flow dev_fl;
1555 dev_fl.is_flow_replicated = false;
1556 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1557 dev_fl.voltha_flow_id = voltha_flow_id;
1558 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params));
1559 // update voltha flow to cache
1560 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1561 }
1562 return st;
1563 } else { // Flow to be replicated
1564 OPENOLT_LOG(INFO, openolt_log_id,"symmetric flow and replication is needed\n");
1565 for (uint8_t i=0; i<NUMBER_OF_REPLICATED_FLOWS; i++) {
1566 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1567 flow_id = dev_fl_symm_params[i].flow_id;
1568 gemport_id = dev_fl_symm_params[i].gemport_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001569 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001570 cl.set_o_pbits(dev_fl_symm_params[i].pbit);
1571 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdrade65ab42020-12-17 23:08:43 -08001572 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001573 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001574 if (st.error_code() != grpc::StatusCode::OK && st.error_code() != grpc::StatusCode::ALREADY_EXISTS) {
1575 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);
1576 // On failure remove any successfully replicated flows installed so far for the voltha_flow_id
1577 if (i > 0) {
1578 for (int8_t j = i-1; j >= 0; j--) {
1579 flow_id = dev_fl_symm_params[j].flow_id;
1580 FlowRemove_(flow_id, flow_type);
1581 }
1582 }
1583 return st;
1584 }
1585 }
1586 device_flow dev_fl;
1587 dev_fl.is_flow_replicated = true;
1588 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1589 dev_fl.voltha_flow_id = voltha_flow_id;
1590 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params)*NUMBER_OF_REPLICATED_FLOWS);
1591 // update voltha flow to cache
1592 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1593 }
1594 } else { // No symmetric flow found
1595 if (!replicate_flow) { // No flow replication
1596 OPENOLT_LOG(INFO, openolt_log_id, "not a symmetric flow and replication is not needed\n");
1597 flow_id = get_flow_id();
1598 if (flow_id == INVALID_FLOW_ID) {
1599 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocated flow id for voltha-flow-id=%lu\n", voltha_flow_id);
1600 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1601 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001602 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001603 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1604 flow_type, alloc_id, network_intf_id, gemport_id, classifier,
Burak Gurdaga0523592021-02-24 15:17:47 +00001605 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001606 if (st.error_code() == grpc::StatusCode::OK) {
1607 device_flow dev_fl;
1608 dev_fl.is_flow_replicated = false;
1609 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // Invalid
1610 dev_fl.voltha_flow_id = voltha_flow_id;
1611 dev_fl.params[0].flow_id = flow_id;
1612 dev_fl.params[0].gemport_id = gemport_id;
1613 dev_fl.params[0].pbit = classifier.o_pbits();
1614 // update voltha flow to cache
1615 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1616 } else {
1617 // Free the flow id on failure
1618 free_flow_id(flow_id);
1619 }
1620 return st;
1621 } else { // Flow to be replicated
1622 OPENOLT_LOG(INFO, openolt_log_id,"not a symmetric flow and replication is needed\n");
1623 if (pbit_to_gemport.size() != NUMBER_OF_PBITS) {
1624 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pbit-to-gemport map size=%lu", pbit_to_gemport.size())
1625 return ::Status(grpc::StatusCode::OUT_OF_RANGE, "pbit-to-gemport-map-len-invalid-for-flow-replication");
1626 }
1627 uint16_t flow_ids[NUMBER_OF_REPLICATED_FLOWS];
1628 device_flow dev_fl;
1629 if (get_flow_ids(NUMBER_OF_REPLICATED_FLOWS, flow_ids)) {
1630 uint8_t cnt = 0;
1631 dev_fl.is_flow_replicated = true;
1632 dev_fl.voltha_flow_id = voltha_flow_id;
1633 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // invalid
1634 for (google::protobuf::Map<unsigned int, unsigned int>::const_iterator it=pbit_to_gemport.begin(); it!=pbit_to_gemport.end(); it++) {
1635 dev_fl.params[cnt].flow_id = flow_ids[cnt];
1636 dev_fl.params[cnt].pbit = it->first;
1637 dev_fl.params[cnt].gemport_id = it->second;
1638
1639 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1640 flow_id = dev_fl.params[cnt].flow_id;
1641 gemport_id = dev_fl.params[cnt].gemport_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001642 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001643 cl.set_o_pbits(dev_fl.params[cnt].pbit);
1644 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1645 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001646 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001647 if (st.error_code() != grpc::StatusCode::OK) {
1648 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);
1649 // Remove any successfully replicated flows installed so far for the voltha_flow_id
1650 if (cnt > 0) {
1651 for (int8_t j = cnt-1; j >= 0; j--) {
1652 flow_id = dev_fl.params[j].flow_id;
1653 FlowRemove_(flow_id, flow_type);
1654 }
1655 }
1656 // Free up all the flow IDs on failure
1657 free_flow_ids(NUMBER_OF_REPLICATED_FLOWS, flow_ids);
1658 return st;
1659 }
1660 cnt++;
1661 }
1662 // On successful flow replication update voltha-flow-id to device-flow map to cache
1663 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1664 } else {
1665 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocate flow ids for replication voltha-flow-id=%lu\n", voltha_flow_id);
1666 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1667 }
1668 }
1669 }
1670
1671 return Status::OK;
1672}
1673
1674
Craig Lutgen967a1d02018-11-27 10:41:51 -06001675Status 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 +00001676 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001677 int32_t alloc_id, int32_t network_intf_id,
1678 int32_t gemport_id, const ::openolt::Classifier& classifier,
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001679 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie,
Burak Gurdaga0523592021-02-24 15:17:47 +00001680 int32_t group_id, uint32_t tech_profile_id, bool aes_enabled) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001681 bcmolt_flow_cfg cfg;
1682 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001683 int32_t o_vid = -1;
1684 bool single_tag = false;
1685 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001686 bcmolt_classifier c_val = { };
1687 bcmolt_action a_val = { };
1688 bcmolt_tm_queue_ref tm_val = { };
1689 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05001690 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001691
Jason Huang09b73ea2020-01-08 17:52:05 +08001692 OPENOLT_LOG(INFO, openolt_log_id, "flow add received for flow_id=%u, flow_type=%s\n", flow_id, flow_type.c_str());
1693
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001694 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001695 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001696 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001697 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001698 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001699 } else if (flow_type.compare(multicast) == 0) {
1700 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001701 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001702 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001703 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001704 }
1705
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001706 BCMOLT_CFG_INIT(&cfg, flow, key);
1707 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001708
Jason Huang09b73ea2020-01-08 17:52:05 +08001709 if (action.cmd().trap_to_host()) {
Girish Gowdra1935e6a2020-10-31 21:48:22 -07001710 Status resp = handle_acl_rule_install(onu_id, flow_id, gemport_id, flow_type, access_intf_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001711 network_intf_id, classifier);
Jason Huang09b73ea2020-01-08 17:52:05 +08001712 return resp;
1713 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001714
1715 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1716
1717 if (access_intf_id >= 0 && network_intf_id >= 0) {
1718 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1719 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1720 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08001721 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1722 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001723 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1724 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1725 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1726 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1727 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001728 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001729 } else {
1730 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
1731 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001732 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001733
Burak Gurdaga0523592021-02-24 15:17:47 +00001734 if (onu_id >= ONU_ID_START) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001735 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
1736 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001737 if (gemport_id >= GEM_PORT_ID_START) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001738 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
1739 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001740 if (gemport_id >= GEM_PORT_ID_START && port_no != 0) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001741 bcmos_fastlock_lock(&data_lock);
1742 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
1743 port_to_flows[port_no].insert(key.flow_id);
1744 flowid_to_gemport[key.flow_id] = gemport_id;
1745 }
1746 else
1747 {
1748 flowid_to_port[key.flow_id] = port_no;
1749 }
1750 bcmos_fastlock_unlock(&data_lock, 0);
1751 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001752
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001753 if (priority_value >= 0) {
1754 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
1755 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301756
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001757 } else { // MULTICAST FLOW
1758 if (group_id >= 0) {
1759 BCMOLT_MSG_FIELD_SET(&cfg, group_id, group_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001760 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001761 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1762 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001763 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001764
1765 {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001766 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001767 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001768 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
1769 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001770 }
1771
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001772 if (classifier.dst_mac().size() > 0) {
1773 bcmos_mac_address d_mac = {};
1774 bcmos_mac_address_init(&d_mac);
1775 memcpy(d_mac.u8, classifier.dst_mac().data(), sizeof(d_mac.u8));
1776 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_mac %02x:%02x:%02x:%02x:%02x:%02x\n", d_mac.u8[0],
1777 d_mac.u8[1], d_mac.u8[2], d_mac.u8[3], d_mac.u8[4], d_mac.u8[5]);
1778 BCMOLT_FIELD_SET(&c_val, classifier, dst_mac, d_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001779 }
1780
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001781 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001782 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001783 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001784 }
1785 */
1786
1787 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001788 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
1789 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001790 }
1791
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001792 if (classifier.dst_ip()) {
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08001793 bcmos_ipv4_address d_ip = {};
1794 bcmos_ipv4_address_init(&d_ip);
1795 d_ip.u32 = classifier.dst_ip();
1796 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_ip %04x\n", d_ip.u32);
1797 BCMOLT_FIELD_SET(&c_val, classifier, dst_ip, d_ip);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001798 }
1799
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08001800 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001801 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001802 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001803 }
1804 */
1805
1806 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001807 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
1808 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001809 }
1810
1811 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001812 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
1813 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001814 }
1815
1816 if (!classifier.pkt_tag_type().empty()) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001817 if (classifier.o_vid()) {
1818 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
1819 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
1820 }
1821
1822 if (classifier.i_vid()) {
1823 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
1824 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
1825 }
1826
1827 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
1828 if (classifier.pkt_tag_type().compare("untagged") == 0) {
1829 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
1830 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
1831 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
1832 single_tag = true;
1833
1834 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301835 // OpenOlt adapter will send 0xFF in case of no pbit classification
1836 // If it is any other value (0 to 7), it is for outer pbit classification.
1837 // OpenFlow protocol does not provide inner pbit classification (in case of double tagged packets),
1838 // and VOLTHA has not used any workaround to solve this problem (for ex: use metadata field).
1839 // Also there exists no use case for i-pbit classification, so we can safely ignore this for now.
1840 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001841 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301842 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001843 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
1844 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001845
Jason Huang09b73ea2020-01-08 17:52:05 +08001846 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301847 // Same comments as in case of "single_tag" packets.
1848 // 0xFF means no pbit classification, otherwise a valid PCP (0 to 7).
1849 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001850 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301851 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001852 }
1853 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001854 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001855 }
1856
Jason Huang09b73ea2020-01-08 17:52:05 +08001857 const ::openolt::ActionCmd& cmd = action.cmd();
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001858
Jason Huang09b73ea2020-01-08 17:52:05 +08001859 if (cmd.add_outer_tag()) {
1860 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
1861 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001862 }
1863
Jason Huang09b73ea2020-01-08 17:52:05 +08001864 if (cmd.remove_outer_tag()) {
1865 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
1866 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
1867 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301868
Jason Huang09b73ea2020-01-08 17:52:05 +08001869 if (action.o_vid()) {
1870 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
1871 o_vid = action.o_vid();
1872 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
1873 }
1874
1875 if (action.o_pbits()) {
1876 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
1877 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
1878 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301879
Jason Huang09b73ea2020-01-08 17:52:05 +08001880 if (action.i_vid()) {
1881 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
1882 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
1883 }
1884
1885 if (action.i_pbits()) {
1886 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
1887 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
1888 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301889
Jason Huang09b73ea2020-01-08 17:52:05 +08001890 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
1891
Burak Gurdaga0523592021-02-24 15:17:47 +00001892 if ((access_intf_id >= 0) && (onu_id >= ONU_ID_START)) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001893 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
1894 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00001895 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 +00001896
Jason Huang09b73ea2020-01-08 17:52:05 +08001897 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1898 // Queue 0 on DS subscriber scheduler
1899 tm_val.queue_id = 0;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001900
Jason Huang09b73ea2020-01-08 17:52:05 +08001901 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1902 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1903 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001904
Jason Huang09b73ea2020-01-08 17:52:05 +08001905 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1906 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1907 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001908
Jason Huang09b73ea2020-01-08 17:52:05 +08001909 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1910 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
1911 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 +00001912
Jason Huang09b73ea2020-01-08 17:52:05 +08001913 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.priority_to_queue.tm_qmp_id, tm_qmp_id);
1916 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 +00001917
Jason Huang09b73ea2020-01-08 17:52:05 +08001918 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
1919 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1920 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1921 }
1922 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
1923 // NNI Scheduler ID
1924 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1925 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1926 // Queue 0 on NNI scheduler
1927 tm_val.queue_id = 0;
1928 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1929 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1930 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001931
Jason Huang09b73ea2020-01-08 17:52:05 +08001932 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 +00001933 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1934 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1935
Jason Huang09b73ea2020-01-08 17:52:05 +08001936 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1937 /* Fetch TM QMP ID mapped to US NNI scheduler */
1938 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
1939 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1940 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1941 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1942 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 +00001943
Jason Huang09b73ea2020-01-08 17:52:05 +08001944 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 +00001945 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1946 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001947 }
Shad Ansari39739bc2018-09-13 21:38:37 +00001948 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301949 } else {
1950 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1951 tm_val.queue_id = 0;
1952
1953 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
1954 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1955 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
1956
1957 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1958 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
1959 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00001960 }
1961
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001962 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001963
Girish Gowdra252f4972020-09-07 21:24:01 -07001964#ifndef SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001965 // BAL 3.1 supports statistics only for unicast flows.
1966 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1967 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
1968 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001969#endif // SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001970
Girish Gowdra252f4972020-09-07 21:24:01 -07001971#ifndef SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001972#ifdef FLOW_CHECKER
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001973 //Flow Checker, To avoid duplicate flow.
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001974 if (flow_id_counters != 0) {
1975 bool b_duplicate_flow = false;
Jason Huang09b73ea2020-01-08 17:52:05 +08001976 std::map<flow_pair, int>::iterator it;
1977
1978 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1979 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(it->first.first, it->first.second, ONU_ID)) && \
1980 (key.flow_type == it->first.second) && \
1981 (cfg.data.svc_port_id == get_flow_status(it->first.first, it->first.second, SVC_PORT_ID)) && \
1982 (cfg.data.priority == get_flow_status(it->first.first, it->first.second, PRIORITY)) && \
1983 (cfg.data.cookie == get_flow_status(it->first.first, it->first.second, COOKIE)) && \
1984 (cfg.data.ingress_intf.intf_type == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_TYPE)) && \
1985 (cfg.data.ingress_intf.intf_id == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_ID)) && \
1986 (cfg.data.egress_intf.intf_type == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_TYPE)) && \
1987 (cfg.data.egress_intf.intf_id == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_ID)) && \
1988 (c_val.o_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_VID)) && \
1989 (c_val.o_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_PBITS)) && \
1990 (c_val.i_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_VID)) && \
1991 (c_val.i_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_PBITS)) && \
1992 (c_val.ether_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_ETHER_TYPE)) && \
1993 (c_val.ip_proto == get_flow_status(it->first.first, it->first.second, CLASSIFIER_IP_PROTO)) && \
1994 (c_val.src_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_SRC_PORT)) && \
1995 (c_val.dst_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_DST_PORT)) && \
1996 (c_val.pkt_tag_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_PKT_TAG_TYPE)) && \
1997 (cfg.data.egress_qos.type == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TYPE)) && \
1998 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_QUEUE_ID)) && \
1999 (cfg.data.egress_qos.tm_sched.id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TM_SCHED_ID)) && \
2000 (a_val.cmds_bitmask == get_flow_status(it->first.first, it->first.second, ACTION_CMDS_BITMASK)) && \
2001 (a_val.o_vid == get_flow_status(it->first.first, it->first.second, ACTION_O_VID)) && \
2002 (a_val.i_vid == get_flow_status(it->first.first, it->first.second, ACTION_I_VID)) && \
2003 (a_val.o_pbits == get_flow_status(it->first.first, it->first.second, ACTION_O_PBITS)) && \
2004 (a_val.i_pbits == get_flow_status(it->first.first, it->first.second, ACTION_I_PBITS)) && \
2005 (cfg.data.state == get_flow_status(it->first.first, it->first.second, STATE)) && \
2006 (cfg.data.group_id == get_flow_status(it->first.first, it->first.second, GROUP_ID));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002007#ifdef SHOW_FLOW_PARAM
2008 // Flow Parameter
2009 FLOW_PARAM_LOG();
2010#endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002011 if (b_duplicate_flow) {
2012 FLOW_LOG(WARNING, "Flow duplicate", 0);
2013 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
2014 }
2015 }
2016 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002017#endif // FLOW_CHECKER
2018#endif // SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002019
2020 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2021 if (err) {
2022 FLOW_LOG(ERROR, "Flow add failed", err);
2023 return bcm_to_grpc_err(err, "flow add failed");
2024 } else {
2025 FLOW_LOG(INFO, "Flow add ok", err);
2026 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002027 flow_map[std::pair<int, int>(key.flow_id,key.flow_type)] = flow_map.size();
2028 flow_id_counters = flow_map.size();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002029 bcmos_fastlock_unlock(&data_lock, 0);
Girish Gowdra252f4972020-09-07 21:24:01 -07002030
2031 }
Burak Gurdaga0523592021-02-24 15:17:47 +00002032
2033 /*
2034 Enable AES encryption on GEM ports if they are used in downstream unicast flows.
2035 Rationale: We can't do upstream encryption in GPON. This change addresses the common denominator (and also minimum viable)
2036 use case for both technologies which is downstream unicast GEM port encryption. Since the downstream traffic is inherently
2037 broadcast to all the ONUs behind a PON port, encrypting the individual subscriber traffic in this direction is important
2038 and considered good enough in terms of security (See Section 12.1 of G.984.3). For upstream unicast and downstream multicast
2039 GEM encryption, we need to make additional changes specific to XGSPON. This will be done as a future work.
2040 */
2041 if (aes_enabled && (access_intf_id >= 0) && (gemport_id >= GEM_PORT_ID_START) && (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM)) {
2042 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);
2043 enable_encryption_for_gem_port(access_intf_id, gemport_id);
2044 } else {
2045 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);
2046 }
2047
Girish Gowdra252f4972020-09-07 21:24:01 -07002048 return Status::OK;
2049}
2050
2051Status FlowRemoveWrapper_(const ::openolt::Flow* request) {
2052 const std::string flow_type = request->flow_type();
2053 uint64_t voltha_flow_id = request->flow_id();
2054 Status st;
2055
2056 // If Voltha flow is not installed, return fail
2057 if (! is_voltha_flow_installed(voltha_flow_id)) {
2058 OPENOLT_LOG(ERROR, openolt_log_id, "voltha_flow_id=%lu not found\n", voltha_flow_id);
2059 return ::Status(grpc::StatusCode::NOT_FOUND, "voltha-flow-not-found");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002060 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04002061
Girish Gowdra252f4972020-09-07 21:24:01 -07002062 const device_flow *dev_fl = get_device_flow(voltha_flow_id);
2063 if (dev_fl == NULL) {
2064 OPENOLT_LOG(ERROR, openolt_log_id, "device flow for voltha_flow_id=%lu in the cache is NULL\n", voltha_flow_id);
2065 return ::Status(grpc::StatusCode::INTERNAL, "device-flow-null-in-cache");
2066 }
2067 if (dev_fl->is_flow_replicated) {
2068 // Note: Here we are ignoring FlowRemove failures
2069 for (int i=0; i<NUMBER_OF_REPLICATED_FLOWS; i++) {
2070 st = FlowRemove_(dev_fl->params[i].flow_id, flow_type);
2071 if (st.error_code() == grpc::StatusCode::OK) {
2072 free_flow_id(dev_fl->params[i].flow_id);
2073 }
2074 }
2075 } else {
2076 // Note: Here we are ignoring FlowRemove failures
2077 st = FlowRemove_(dev_fl->params[0].flow_id, flow_type);
2078 if (st.error_code() == grpc::StatusCode::OK) {
2079 free_flow_id(dev_fl->params[0].flow_id);
2080 }
2081 }
2082 // remove the flow from cache on voltha flow removal
2083 remove_voltha_flow_from_cache(voltha_flow_id);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002084 return Status::OK;
2085}
2086
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002087Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
2088
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002089 bcmolt_flow_cfg cfg;
2090 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002091
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002092 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002093 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002094 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002095 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002096 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002097 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002098 } else if(flow_type.compare(multicast) == 0) {
2099 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002100 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002101 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002102 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
2103 }
2104
Jason Huang09b73ea2020-01-08 17:52:05 +08002105 OPENOLT_LOG(INFO, openolt_log_id, "flow remove received for flow_id=%u, flow_type=%s\n",
2106 flow_id, flow_type.c_str());
2107
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002108 bcmos_fastlock_lock(&acl_packet_trap_handler_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002109 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
2110 int32_t gemport_id = -1;
2111 int32_t intf_id = -1;
2112 int16_t acl_id = -1;
2113 if (flow_to_acl_map.count(fl_id_fl_dir) > 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002114
2115 acl_id_intf_id ac_id_if_id = flow_to_acl_map[fl_id_fl_dir];
2116 acl_id = std::get<0>(ac_id_if_id);
2117 intf_id = std::get<1>(ac_id_if_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002118 // cleanup acl only if it is a valid acl. If not valid acl, it may be datapath flow.
2119 if (acl_id >= 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002120 Status resp = handle_acl_rule_cleanup(acl_id, intf_id, flow_type);
Jason Huang09b73ea2020-01-08 17:52:05 +08002121 if (resp.ok()) {
2122 OPENOLT_LOG(INFO, openolt_log_id, "acl removed ok for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2123 flow_to_acl_map.erase(fl_id_fl_dir);
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002124
2125 // 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
2126 if (trap_to_host_pkt_info_with_vlan_for_flow_id.count(flow_id) > 0) {
2127 trap_to_host_pkt_info_with_vlan pkt_info_with_vlan = trap_to_host_pkt_info_with_vlan_for_flow_id[flow_id];
2128 // Formulate the trap_to_host_pkt_info tuple key
2129 trap_to_host_pkt_info pkt_info(std::get<0>(pkt_info_with_vlan),
2130 std::get<1>(pkt_info_with_vlan),
2131 std::get<2>(pkt_info_with_vlan),
2132 std::get<3>(pkt_info_with_vlan));
2133 // Extract the value corresponding to trap_to_host_pkt_info key from trap_to_host_vlan_ids_for_trap_to_host_pkt_info
2134 // The value is a list of vlan_ids for the given trap_to_host_pkt_info key
2135 // Remove the vlan_id from the list that corresponded to the flow being removed.
2136 if (trap_to_host_vlan_ids_for_trap_to_host_pkt_info.count(pkt_info) > 0) {
2137 trap_to_host_vlan_ids_for_trap_to_host_pkt_info[pkt_info].remove(std::get<4>(pkt_info_with_vlan));
2138 } else {
2139 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",
2140 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));
2141 }
2142
2143 } else {
2144 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);
2145 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002146 } else {
2147 OPENOLT_LOG(ERROR, openolt_log_id, "acl remove error for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2148 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002149 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002150 return resp;
2151 }
2152 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002153 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002154
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002155 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002156 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002157 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002158 flowid_to_gemport.erase(key.flow_id);
2159 port_to_flows[port_no].erase(key.flow_id);
2160 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
2161 }
2162 else
2163 {
2164 flowid_to_port.erase(key.flow_id);
2165 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002166 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002167
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002168 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002169
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002170 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002171 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002172 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 -04002173 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
2174 }
2175
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002176 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002177 if (flow_id_counters != 0) {
2178 std::map<flow_pair, int>::iterator it;
2179 for(it = flow_map.begin(); it != flow_map.end(); it++) {
2180 if (it->first.first == flow_id && it->first.second == key.flow_type) {
2181 flow_id_counters -= 1;
2182 flow_map.erase(it);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002183 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002184 }
2185 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002186 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
2187
Jason Huang09b73ea2020-01-08 17:52:05 +08002188 flow_to_acl_map.erase(fl_id_fl_dir);
2189
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002190 bcmos_fastlock_unlock(&data_lock, 0);
2191
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002192 return Status::OK;
2193}
2194
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002195bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
2196 bcmos_errno err;
2197 bcmolt_tm_sched_cfg tm_sched_cfg;
2198 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2199 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
2200
Jason Huangbf45ffb2019-10-30 17:29:02 +08002201 //check TM scheduler has configured or not
2202 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2203 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002204 #ifdef TEST_MODE
2205 // It is impossible to mock the setting of tm_sched_cfg.data.state because
2206 // the actual bcmolt_cfg_get passes the address of tm_sched_cfg.hdr and we cannot
2207 // set the tm_sched_cfg.data.state. So a new stub function is created and address
2208 // of tm_sched_cfg is passed. This is one-of case where we need to add test specific
2209 // code in production code.
2210 err = bcmolt_cfg_get__tm_sched_stub(dev_id, &tm_sched_cfg);
2211 #else
Jason Huangbf45ffb2019-10-30 17:29:02 +08002212 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002213 #endif
Jason Huangbf45ffb2019-10-30 17:29:02 +08002214 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002215 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 +08002216 return err;
2217 }
2218 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
2219 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
2220 return BCM_ERR_OK;
2221 }
2222
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002223 // bcmbal_tm_sched_owner
2224 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2225
2226 /**< The output of the tm_sched object instance */
2227 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
2228
2229 if (direction.compare(upstream) == 0) {
2230 // In upstream it is NNI scheduler
2231 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
2232 } else if (direction.compare(downstream) == 0) {
2233 // In downstream it is PON scheduler
2234 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2235 }
2236
2237 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2238
2239 // bcmbal_tm_sched_type
2240 // set the deafult policy to strict priority
2241 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2242
2243 // num_priorities: Max number of strict priority scheduling elements
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002244 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, NUM_OF_PRIORITIES);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002245
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002246 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2247 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002248 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
2249 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002250 return err;
2251 }
2252
2253 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2254 direction.c_str(), tm_sched_key.id, intf_id);
2255 return BCM_ERR_OK;
2256}
2257
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002258bcmos_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 -07002259 uint32_t alloc_id, ::tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
2260 ::tech_profile::SchedulingPolicy sched_policy, ::tech_profile::TrafficShapingInfo tf_sh_info,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002261 uint32_t tech_profile_id) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002262
2263 bcmos_errno err;
2264
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002265 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002266 bcmolt_tm_sched_cfg tm_sched_cfg;
2267 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002268 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 -04002269
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002270 // bcmbal_tm_sched_owner
2271 // In downstream it is sub_term scheduler
2272 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002273
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002274 /**< The output of the tm_sched object instance */
2275 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002276
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002277 // bcmbal_tm_sched_parent
2278 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2279 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
2280 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 +00002281 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002282 be achieved using the' virtual' type of attachment.
2283 tm_sched_owner.u.sub_term.intf_id = intf_id;
2284 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2285 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002286
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002287 // bcmbal_tm_sched_type
2288 // set the deafult policy to strict priority
2289 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002290
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002291 // num_priorities: Max number of strict priority scheduling elements
2292 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002293
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002294 // bcmbal_tm_shaping
2295 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2296 uint32_t cir = tf_sh_info.cir();
2297 uint32_t pir = tf_sh_info.pir();
2298 uint32_t burst = tf_sh_info.pbs();
2299 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2300 cir, pir, burst);
2301 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2302 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2303 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2304 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2305 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2306 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002307 }
2308
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002309 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002310 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002311 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002312intf_id %d, onu_id %d, uni_id %d, port_no %u, err = %s\n", tm_sched_key.id, intf_id, onu_id, uni_id, \
2313port_no, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002314 return err;
2315 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002316 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2317uni_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 -08002318
2319 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002320 bcmolt_itupon_alloc_cfg cfg;
2321 bcmolt_itupon_alloc_key key = { };
2322 key.pon_ni = intf_id;
2323 key.alloc_id = alloc_id;
2324 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
Burak Gurdag623fada2021-04-20 22:02:36 +00002325 /*
2326 PIR: Maximum Bandwidth
2327 CIR: Assured Bandwidth
2328 GIR: Fixed Bandwidth
2329 */
Burak Gurdag03919c72020-02-04 22:46:57 +00002330 int pir_bw = tf_sh_info.pir()*125; // conversion from kbps to bytes/sec
2331 int cir_bw = tf_sh_info.cir()*125; // conversion from kbps to bytes/sec
Burak Gurdag623fada2021-04-20 22:02:36 +00002332 int gir_bw = tf_sh_info.gir()*125; // conversion from kbps to bytes/sec
2333 int guaranteed_bw = cir_bw+gir_bw;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002334 //offset to match bandwidth granularity
2335 int offset_pir_bw = pir_bw%bw_granularity;
Burak Gurdag623fada2021-04-20 22:02:36 +00002336 int offset_gir_bw = gir_bw%bw_granularity;
2337 int offset_guaranteed_bw = guaranteed_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002338
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002339 pir_bw = pir_bw - offset_pir_bw;
Burak Gurdag623fada2021-04-20 22:02:36 +00002340 gir_bw = gir_bw - offset_gir_bw;
2341 guaranteed_bw = guaranteed_bw - offset_guaranteed_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002342
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002343 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002344
Burak Gurdag623fada2021-04-20 22:02:36 +00002345 OPENOLT_LOG(INFO, openolt_log_id, "Creating alloc_id %d with pir = %d bytes/sec, cir = %d bytes/sec, gir = %d bytes/sec, additional_bw = %d.\n", alloc_id, pir_bw, cir_bw, gir_bw, additional_bw);
2346
2347 if (pir_bw == 0) {
2348 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be at least %d bytes/sec\n",
2349 (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2350 return BCM_ERR_PARM;
2351 } else if (pir_bw < guaranteed_bw) {
2352 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed bandwidth (%d)\n",
2353 pir_bw, guaranteed_bw);
2354 return BCM_ERR_PARM;
2355 }
2356
2357 // Setting additional bw eligibility and validating bw provisionings
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002358 switch (additional_bw) {
Burak Gurdag623fada2021-04-20 22:02:36 +00002359
2360 case tech_profile::AdditionalBW::AdditionalBW_BestEffort: //AdditionalBW_BestEffort - For T-Cont types 4 & 5
2361 if (pir_bw == guaranteed_bw) {
2362 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2363bandwidth for additional bandwidth eligibility of type Best Effort\n");
2364 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002365 }
2366 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2367 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002368
2369 case tech_profile::AdditionalBW::AdditionalBW_NA: //AdditionalBW_NA - For T-Cont types 3 & 5
2370 if (guaranteed_bw == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002371 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2372additional bandwidth eligibility of type Non-Assured (NA)\n");
2373 return BCM_ERR_PARM;
Burak Gurdag623fada2021-04-20 22:02:36 +00002374 } else if (pir_bw == guaranteed_bw) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002375 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
Burak Gurdag623fada2021-04-20 22:02:36 +00002376bandwidth for additional bandwidth eligibility of type Non-Assured\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002377 return BCM_ERR_PARM;
2378 }
2379 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2380 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002381
2382 case tech_profile::AdditionalBW::AdditionalBW_None: //AdditionalBW_None - For T-Cont types 1 & 2
2383 if (guaranteed_bw != pir_bw) {
2384 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be equal to maximum bandwidth \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002385for additional bandwidth eligibility of type None\n");
2386 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002387 }
2388 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2389 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002390
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002391 default:
Burak Gurdag623fada2021-04-20 22:02:36 +00002392 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid additional bandwidth eligibility value (%d) supplied.\n", additional_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002393 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002394 }
Burak Gurdag623fada2021-04-20 22:02:36 +00002395
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002396 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2397 in a fine granularity. */
2398 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
Burak Gurdag623fada2021-04-20 22:02:36 +00002399 /* Since we can assign minimum 64000 bytes/sec for cbr_rt_bw, we prefer assigning
2400 gir_bw to cbr_nrt_bw to allow smaller amounts.
2401 TODO: Specify CBR_RT_BW and CBR_NRT_BW separately from VOLTHA */
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002402 /* Fixed Bandwidth with no critical requirement of shaping */
Burak Gurdag623fada2021-04-20 22:02:36 +00002403 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, gir_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002404 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
Burak Gurdag623fada2021-04-20 22:02:36 +00002405 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, guaranteed_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002406 /* Maximum allocated bandwidth allowed for this alloc ID */
2407 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
Burak Gurdag623fada2021-04-20 22:02:36 +00002408
2409 if (pir_bw == gir_bw) { // T-Cont Type 1 --> set alloc type to NONE
2410 // the condition cir_bw == 0 is implicitly satistied
2411 OPENOLT_LOG(INFO, openolt_log_id, "Setting alloc type to NONE since maximum bandwidth is equal to fixed bandwidth\n");
2412 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NONE);
2413 } else { // For other T-Cont types, set alloc type to NSR. TODO: read the default from a config file.
2414 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
2415 }
2416
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002417 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002418 for skipped allocations during quiet window */
2419 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2420 /**< Allocation Profile index for CBR non-RT Bandwidth */
2421 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2422 /**< Allocation Profile index for CBR RT Bandwidth */
2423 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2424 /**< Alloc ID Weight used in case of Extended DBA mode */
2425 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2426 /**< Alloc ID Priority used in case of Extended DBA mode */
2427 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2428 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002429
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002430 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002431 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002432 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
Burak Gurdag623fada2021-04-20 22:02:36 +00002433port_no %u, alloc_id %d, err = %s (%s)\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err), cfg.hdr.hdr.err_text);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002434 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002435 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002436#ifndef SCALE_AND_PERF
Girish Gowdra96461052019-11-22 20:13:59 +05302437 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
2438 if (err) {
2439 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2440port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
2441 return err;
2442 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002443#endif
Girish Gowdra96461052019-11-22 20:13:59 +05302444
2445 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
2446port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
2447
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002448 }
2449
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002450 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002451}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002452
Girish Gowdra252f4972020-09-07 21:24:01 -07002453Status CreateTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002454 uint32_t intf_id = traffic_scheds->intf_id();
2455 uint32_t onu_id = traffic_scheds->onu_id();
2456 uint32_t uni_id = traffic_scheds->uni_id();
2457 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002458 std::string direction;
2459 unsigned int alloc_id;
Girish Gowdra252f4972020-09-07 21:24:01 -07002460 ::tech_profile::SchedulerConfig sched_config;
2461 ::tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002462 uint32_t priority;
2463 uint32_t weight;
Girish Gowdra252f4972020-09-07 21:24:01 -07002464 ::tech_profile::SchedulingPolicy sched_policy;
2465 ::tech_profile::TrafficShapingInfo traffic_shaping_info;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002466 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002467 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002468
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002469 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002470 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002471
2472 direction = GetDirection(traffic_sched.direction());
2473 if (direction.compare("direction-not-supported") == 0)
2474 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2475
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002476 alloc_id = traffic_sched.alloc_id();
2477 sched_config = traffic_sched.scheduler();
2478 additional_bw = sched_config.additional_bw();
2479 priority = sched_config.priority();
2480 weight = sched_config.weight();
2481 sched_policy = sched_config.sched_policy();
2482 traffic_shaping_info = traffic_sched.traffic_shaping_info();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002483 tech_profile_id = traffic_sched.tech_profile_id();
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002484 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002485 sched_policy, traffic_shaping_info, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002486 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002487 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002488 return bcm_to_grpc_err(err, "Failed to create scheduler");
2489 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002490 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002491 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002492}
Jonathan Davis70c21812018-07-19 15:32:10 -04002493
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002494bcmos_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 -04002495
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002496 bcmos_errno err;
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302497 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302498 bcmolt_status los_status;
Girish Gowdra96461052019-11-22 20:13:59 +05302499 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002500
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002501 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002502 bcmolt_itupon_alloc_cfg cfg;
2503 bcmolt_itupon_alloc_key key = { };
2504 key.pon_ni = intf_id;
2505 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302506 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002507
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002508 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002509 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2510 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002511 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2512 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002513 return err;
2514 }
Girish Gowdra96461052019-11-22 20:13:59 +05302515
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302516 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302517 if (err == BCM_ERR_OK) {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302518 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_OFF) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002519#ifndef SCALE_AND_PERF
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302520 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 +05302521 intf_id);
2522 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2523 if (err) {
2524 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2525 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
2526 return err;
2527 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002528#endif
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302529 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302530 else if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_ON) {
2531 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is enabled but LoS status is ON, not waiting for alloc cfg clear response\n",
2532 intf_id);
2533 }
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302534 else if (state == BCMOLT_INTERFACE_STATE_INACTIVE) {
2535 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is disabled, not waiting for alloc cfg clear response\n",
2536 intf_id);
2537 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302538 } else {
2539 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 +05302540 intf_id, bcmos_strerror(err));
Girish Gowdra96461052019-11-22 20:13:59 +05302541 return err;
2542 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002543 } else if (direction == downstream) {
2544 bcmolt_tm_sched_cfg cfg;
2545 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002546
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002547 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2548 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302549 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002550 } else {
2551 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2552 return BCM_ERR_OK;
2553 }
Girish Gowdra96461052019-11-22 20:13:59 +05302554
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002555 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2556 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2557 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002558 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002559intf_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 +00002560 return err;
2561 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002562 }
2563
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002564 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d, tech_profile_id %d\n",
2565 direction.c_str(), sched_id, intf_id, onu_id, tech_profile_id);
2566 free_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002567 return BCM_ERR_OK;
2568}
2569
Girish Gowdra252f4972020-09-07 21:24:01 -07002570Status RemoveTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002571 uint32_t intf_id = traffic_scheds->intf_id();
2572 uint32_t onu_id = traffic_scheds->onu_id();
2573 uint32_t uni_id = traffic_scheds->uni_id();
2574 std::string direction;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002575 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002576 bcmos_errno err;
2577
2578 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002579 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002580
2581 direction = GetDirection(traffic_sched.direction());
2582 if (direction.compare("direction-not-supported") == 0)
2583 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2584
2585 int alloc_id = traffic_sched.alloc_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002586 int tech_profile_id = traffic_sched.tech_profile_id();
2587 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002588 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002589 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002590 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2591 }
2592 }
2593 return Status::OK;
2594}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002595
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002596bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2597 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002598 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002599 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2600 bcmolt_tm_qmp_key tm_qmp_key;
2601 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002602
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002603 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2604 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002605 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed tm queue mapping profile count is 16.\n");
2606 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002607 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002608
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002609 tm_qmp_key.id = tm_qmp_id;
2610 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2611 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2612 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002613
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002614 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2615 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2616 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002617 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2618 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002619
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002620 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002621 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002622 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2623 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002624 return err;
2625 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002626
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002627 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2628 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002629 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002630}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002631
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002632bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2633 bcmos_errno err;
2634 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2635 bcmolt_tm_qmp_key tm_qmp_key;
2636 tm_qmp_key.id = tm_qmp_id;
2637
2638 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2639 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2640 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002641 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2642 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002643 return err;
2644 }
2645
2646 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2647 tm_qmp_key.id);
2648 return BCM_ERR_OK;
2649}
2650
2651bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2652 bcmos_errno err;
2653
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002654 /* Create default queues on the given PON/NNI scheduler */
2655 for (int queue_id = 0; queue_id < NUMBER_OF_DEFAULT_INTERFACE_QUEUES; queue_id++) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002656 bcmolt_tm_queue_cfg tm_queue_cfg;
2657 bcmolt_tm_queue_key tm_queue_key = {};
2658 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2659 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002660 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2661 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2662 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002663
2664 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2665 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2666 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2667
2668 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2669 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002670 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", \
2671 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 +00002672 return err;
2673 }
2674
2675 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2676 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2677 }
2678 return BCM_ERR_OK;
2679}
2680
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002681bcmos_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 +00002682 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 +00002683 bcmos_errno err;
2684 bcmolt_tm_queue_cfg cfg;
2685 bcmolt_tm_queue_key key = { };
2686 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 +00002687gemport_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 +00002688
2689 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002690 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002691
2692 if (priority > 7) {
2693 return BCM_ERR_RANGE;
2694 }
2695
2696 /* FIXME: The upstream queues have to be created once only.
2697 The upstream queues on the NNI scheduler are shared by all subscribers.
2698 When the first scheduler comes in, the queues get created, and are re-used by all others.
2699 Also, these queues should be present until the last subscriber exits the system.
2700 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2701
2702 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2703 for each GEM in TECH PROFILE */
2704 key.id = queue_id_list[priority];
2705
2706 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2707 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2708 key.id = 0;
2709 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2710 }
2711 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2712 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2713 }
2714 else {
2715 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2716 }
2717
2718 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2719
2720 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2721 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
2722
2723 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2724 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002725 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002726sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, tech_profile_id %d, err = %s\n", \
2727 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 +00002728 return err;
2729 }
2730
Girish Gowdra252f4972020-09-07 21:24:01 -07002731 if (direction.compare(upstream) == 0) {
2732 Status st = install_gem_port(access_intf_id, onu_id, gemport_id);
2733 if (st.error_code() != grpc::StatusCode::ALREADY_EXISTS && st.error_code() != grpc::StatusCode::OK) {
2734 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);
2735 return BCM_ERR_INTERNAL;
2736 }
2737 }
2738
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002739 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 +00002740intf_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 +00002741 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002742}
2743
Girish Gowdra252f4972020-09-07 21:24:01 -07002744Status CreateTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002745 uint32_t intf_id = traffic_queues->intf_id();
2746 uint32_t onu_id = traffic_queues->onu_id();
2747 uint32_t uni_id = traffic_queues->uni_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002748 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002749 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002750 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002751 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002752 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 +00002753
2754 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2755 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2756 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2757 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002758 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002759
2760 direction = GetDirection(traffic_queue.direction());
2761 if (direction.compare("direction-not-supported") == 0)
2762 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2763
2764 queues_priority_q[i] = traffic_queue.priority();
2765 queues_pbit_map[i] = traffic_queue.pbit_map();
2766 }
2767
2768 std::vector<uint32_t> tmq_map_profile(8, 0);
2769 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2770 queues_priority_q, COUNT_OF(queues_priority_q));
2771 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002772 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002773
2774 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2775 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002776 err = CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2777 if (err != BCM_ERR_OK) {
2778 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2779 return bcm_to_grpc_err(err, "Failed to create tm queue mapping profile");
2780 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002781 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2782 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2783 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2784 }
2785 }
2786
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002787 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002788 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002789
2790 direction = GetDirection(traffic_queue.direction());
2791 if (direction.compare("direction-not-supported") == 0)
2792 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2793
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002794 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 +00002795
Girish Gowdruf26cf882019-05-01 23:47:58 -07002796 // If the queue exists already, lets not return failure and break the loop.
2797 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002798 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002799 return bcm_to_grpc_err(err, "Failed to create queue");
2800 }
2801 }
2802 return Status::OK;
2803}
2804
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002805bcmos_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 +00002806 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 +00002807 bcmolt_tm_queue_cfg cfg;
2808 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002809 bcmos_errno err;
2810
2811 if (direction == downstream) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002812 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2813 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 +00002814 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002815 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002816 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 -08002817 return BCM_ERR_OK;
2818 }
2819 } else {
Girish Gowdra4fd30672020-11-09 17:23:06 -08002820 // Gemports are bi-directional (except in multicast case). We create the gem port when we create the
2821 // upstream queue (see CreateQueue function) and it makes sense to delete them when remove the upstream queues.
2822 // For multicast case we do not manage the install/remove of gem port in agent application. It is managed by BAL.
2823 // Moreover it also makes sense to remove when upstream queue is getting removed because the upstream queue MUST exist always.
2824 // It is possible that the downstream queues are not created for a subscriber (for ex: upstream EAPoL trap flow only exists
2825 // but no other flow, and in this case only upstream scheduler and queues exist. We do not have a scenario where only downstream
2826 // subscriber flows exist but no upstream )
2827 remove_gem_port(access_intf_id, gemport_id);
2828
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002829 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2830 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002831 return BCM_ERR_OK;
2832 }
2833
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002834 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2835 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2836 // Reset the queue id to 0 when using fixed queue.
2837 key.id = 0;
2838 }
2839 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2840 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2841 }
2842 else {
2843 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2844 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002845
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002846 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2847 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002848 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002849 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, queue_id %d, sched_id %d, \
2850tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n",
2851 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 -08002852 return err;
2853 }
2854
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002855 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2856intf_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 -08002857
2858 return BCM_ERR_OK;
2859}
2860
Girish Gowdra252f4972020-09-07 21:24:01 -07002861Status RemoveTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002862 uint32_t intf_id = traffic_queues->intf_id();
2863 uint32_t onu_id = traffic_queues->onu_id();
2864 uint32_t uni_id = traffic_queues->uni_id();
2865 uint32_t port_no = traffic_queues->port_no();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002866 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002867 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002868 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002869 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002870 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 +00002871
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002872 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002873 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002874
2875 direction = GetDirection(traffic_queue.direction());
2876 if (direction.compare("direction-not-supported") == 0)
2877 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2878
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002879 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 -08002880 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002881 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002882 return bcm_to_grpc_err(err, "Failed to remove queue");
2883 }
Jonathan Davis70c21812018-07-19 15:32:10 -04002884 }
2885
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002886 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 +00002887 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002888 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002889
2890 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
2891 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002892 err = RemoveTrafficQueueMappingProfile(tm_qmp_id);
2893 if (err != BCM_ERR_OK) {
2894 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2895 return bcm_to_grpc_err(err, "Failed to remove tm queue mapping profile");
2896 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002897 }
2898 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002899 clear_qos_type(intf_id, onu_id, uni_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04002900 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04002901}
Jason Huangbf45ffb2019-10-30 17:29:02 +08002902
Girish Gowdra252f4972020-09-07 21:24:01 -07002903Status PerformGroupOperation_(const ::openolt::Group *group_cfg) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002904
2905 bcmos_errno err;
2906 bcmolt_group_key key = {};
2907 bcmolt_group_cfg grp_cfg_obj;
2908 bcmolt_group_members_update grp_mem_upd;
2909 bcmolt_members_update_command grp_mem_upd_cmd;
2910 bcmolt_group_member_info member_info = {};
2911 bcmolt_group_member_info_list_u8 members = {};
2912 bcmolt_intf_ref interface_ref = {};
2913 bcmolt_egress_qos egress_qos = {};
2914 bcmolt_tm_sched_ref tm_sched_ref = {};
2915 bcmolt_action a_val = {};
2916
2917 uint32_t group_id = group_cfg->group_id();
2918
2919 OPENOLT_LOG(INFO, openolt_log_id, "PerformGroupOperation request received for Group %d\n", group_id);
2920
2921 if (group_id >= 0) {
2922 key.id = group_id;
2923 }
2924 else {
2925 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
2926 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
2927 }
2928
2929 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2930 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
2931
2932 OPENOLT_LOG(INFO, openolt_log_id, "Checking if Group %d exists...\n",group_id);
2933
2934 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
2935 if (err != BCM_ERR_OK) {
2936 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
2937 return bcm_to_grpc_err(err, "Error in querying group");
2938 }
2939
2940 members.len = group_cfg->members_size();
2941
2942 // IMPORTANT: A member cannot be added to a group if the group type is not determined.
2943 // Group type is determined after a flow is assigned to it.
2944 // Therefore, a group must be created first, then a flow (with multicast type) must be assigned to it.
2945 // Only then we can add members to the group.
2946
2947 // if group does not exist, create it and return.
2948 if (grp_cfg_obj.data.state == BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
2949
2950 if (members.len != 0) {
2951 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);
2952 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Non-empty member list given for non-existent group");
2953 } else {
2954
2955 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2956 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, cookie, key.id);
2957
2958 /* Setting group actions and action parameters, if any.
2959 Only remove_outer_tag and translate_inner_tag actions and i_vid action parameter
2960 are supported for multicast groups in BAL 3.1.
2961 */
2962 const ::openolt::Action& action = group_cfg->action();
2963 const ::openolt::ActionCmd &cmd = action.cmd();
2964
2965 bcmolt_action_cmd_id cmd_bmask = BCMOLT_ACTION_CMD_ID_NONE;
2966 if (cmd.remove_outer_tag()) {
2967 OPENOLT_LOG(INFO, openolt_log_id, "Action remove_outer_tag applied to Group %d.\n", group_id);
2968 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
2969 }
2970
2971 if (cmd.translate_inner_tag()) {
2972 OPENOLT_LOG(INFO, openolt_log_id, "Action translate_inner_tag applied to Group %d.\n", group_id);
2973 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG);
2974 }
2975
2976 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, cmd_bmask);
2977
2978 if (action.i_vid()) {
2979 OPENOLT_LOG(INFO, openolt_log_id, "Setting action parameter i_vid=%d for Group %d.\n", action.i_vid(), group_id);
2980 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
2981 }
2982
2983 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, action, a_val);
2984
2985 // Create group
2986 err = bcmolt_cfg_set(dev_id, &(grp_cfg_obj.hdr));
2987
2988 if (BCM_ERR_OK != err) {
2989 BCM_LOG(ERROR, openolt_log_id, "Failed to create Group %d, err = %s (%d)\n", key.id, bcmos_strerror(err), err);
2990 return bcm_to_grpc_err(err, "Error in creating group");
2991 }
2992
2993 BCM_LOG(INFO, openolt_log_id, "Group %d has been created and configured with empty member list.\n", key.id);
2994 return Status::OK;
2995 }
2996 }
2997
2998 // The group already exists. Continue configuring it according to the update member command.
2999
3000 OPENOLT_LOG(INFO, openolt_log_id, "Configuring existing Group %d.\n",group_id);
3001
3002 // MEMBER LIST CONSTRUCTION
3003 // Note that members.len can be 0 here. if the group already exists and the command is SET then sending
3004 // empty list to the group is a legit operation and this actually empties the member list.
3005 members.arr = (bcmolt_group_member_info*)bcmos_calloc((members.len)*sizeof(bcmolt_group_member_info));
3006
3007 if (!members.arr) {
3008 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to allocate memory for group member list.\n");
3009 return grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "Memory exhausted during member list creation");
3010 }
3011
3012 /* SET GROUP MEMBERS UPDATE COMMAND */
Girish Gowdra252f4972020-09-07 21:24:01 -07003013 ::openolt::Group::GroupMembersCommand command = group_cfg->command();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003014 switch(command) {
Girish Gowdra252f4972020-09-07 21:24:01 -07003015 case ::openolt::Group::SET_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003016 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_SET;
3017 OPENOLT_LOG(INFO, openolt_log_id, "Setting %d members for Group %d.\n", members.len, group_id);
3018 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003019 case ::openolt::Group::ADD_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003020 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_ADD;
3021 OPENOLT_LOG(INFO, openolt_log_id, "Adding %d members to Group %d.\n", members.len, group_id);
3022 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003023 case ::openolt::Group::REMOVE_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003024 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_REMOVE;
3025 OPENOLT_LOG(INFO, openolt_log_id, "Removing %d members from Group %d.\n", members.len, group_id);
3026 break;
3027 default :
3028 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid value %d for group member command.\n", command);
3029 bcmos_free(members.arr);
3030 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group member command");
3031 }
3032
3033 // SET MEMBERS LIST
3034 for (int i = 0; i < members.len; i++) {
3035
Girish Gowdra252f4972020-09-07 21:24:01 -07003036 if (command == ::openolt::Group::REMOVE_MEMBERS) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003037 OPENOLT_LOG(INFO, openolt_log_id, "Removing group member %d from group %d\n",i,key.id);
3038 } else {
3039 OPENOLT_LOG(INFO, openolt_log_id, "Adding group member %d to group %d\n",i,key.id);
3040 }
3041
Girish Gowdra252f4972020-09-07 21:24:01 -07003042 ::openolt::GroupMember *member = (::openolt::GroupMember *) &group_cfg->members()[i];
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003043
3044 // Set member interface type
Girish Gowdra252f4972020-09-07 21:24:01 -07003045 ::openolt::GroupMember::InterfaceType if_type = member->interface_type();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003046 switch(if_type){
Girish Gowdra252f4972020-09-07 21:24:01 -07003047 case ::openolt::GroupMember::PON :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003048 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_PON);
3049 OPENOLT_LOG(INFO, openolt_log_id, "Interface type PON is assigned to GroupMember %d\n",i);
3050 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003051 case ::openolt::GroupMember::EPON_1G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003052 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_1_G);
3053 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_1G is assigned to GroupMember %d\n",i);
3054 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003055 case ::openolt::GroupMember::EPON_10G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003056 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_10_G);
3057 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_10G is assigned to GroupMember %d\n",i);
3058 break;
3059 default :
3060 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid interface type value %d for GroupMember %d.\n",if_type,i);
3061 bcmos_free(members.arr);
3062 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface type for a group member");
3063 }
3064
3065 // Set member interface id
3066 if (member->interface_id() >= 0) {
3067 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_id, member->interface_id());
3068 OPENOLT_LOG(INFO, openolt_log_id, "Interface %d is assigned to GroupMember %d\n", member->interface_id(), i);
3069 } else {
3070 bcmos_free(members.arr);
3071 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface id for a group member");
3072 }
3073
3074 // Set member interface_ref
3075 BCMOLT_FIELD_SET(&member_info, group_member_info, intf, interface_ref);
3076
3077 // Set member gem_port_id. This must be a multicast gemport.
3078 if (member->gem_port_id() >= 0) {
3079 BCMOLT_FIELD_SET(&member_info, group_member_info, svc_port_id, member->gem_port_id());
3080 OPENOLT_LOG(INFO, openolt_log_id, "GEM Port %d is assigned to GroupMember %d\n", member->gem_port_id(), i);
3081 } else {
3082 bcmos_free(members.arr);
3083 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid gem port id for a group member");
3084 }
3085
3086 // Set member scheduler id and queue_id
3087 uint32_t tm_sched_id = get_default_tm_sched_id(member->interface_id(), downstream);
3088 OPENOLT_LOG(INFO, openolt_log_id, "Scheduler %d is assigned to GroupMember %d\n", tm_sched_id, i);
3089 BCMOLT_FIELD_SET(&tm_sched_ref, tm_sched_ref, id, tm_sched_id);
3090 BCMOLT_FIELD_SET(&egress_qos, egress_qos, tm_sched, tm_sched_ref);
3091
3092 // We assume that all multicast traffic destined to a PON port is using the same fixed queue.
3093 uint32_t tm_queue_id;
3094 if (member->priority() >= 0 && member->priority() < NUMBER_OF_DEFAULT_INTERFACE_QUEUES) {
3095 tm_queue_id = queue_id_list[member->priority()];
3096 OPENOLT_LOG(INFO, openolt_log_id, "Queue %d is assigned to GroupMember %d\n", tm_queue_id, i);
3097 BCMOLT_FIELD_SET(&egress_qos, egress_qos, type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
3098 BCMOLT_FIELD_SET(&egress_qos.u.fixed_queue, egress_qos_fixed_queue, queue_id, tm_queue_id);
3099 } else {
3100 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid fixed queue priority/ID %d for GroupMember %d\n", member->priority(), i);
3101 bcmos_free(members.arr);
3102 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid queue priority for a group member");
3103 }
3104
3105 BCMOLT_FIELD_SET(&member_info, group_member_info, egress_qos, egress_qos);
3106 BCMOLT_ARRAY_ELEM_SET(&(members), i, member_info);
3107 }
3108
3109 BCMOLT_OPER_INIT(&grp_mem_upd, group, members_update, key);
3110 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.members, members);
3111 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.command, grp_mem_upd_cmd);
3112
3113 err = bcmolt_oper_submit(dev_id, &(grp_mem_upd.hdr));
3114 bcmos_free(members.arr);
3115
3116 if (BCM_ERR_OK != err) {
3117 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);
3118 return bcm_to_grpc_err(err, "Failed to submit members update operation for the group");
3119 }
3120
3121 OPENOLT_LOG(INFO, openolt_log_id, "Successfully submitted members update operation for Group %d\n", key.id);
3122
3123 return Status::OK;
3124}
Burak Gurdageb4ca2e2020-06-15 07:48:26 +00003125
3126Status DeleteGroup_(uint32_t group_id) {
3127
3128 bcmos_errno err = BCM_ERR_OK;
3129 bcmolt_group_cfg grp_cfg_obj;
3130 bcmolt_group_key key = {};
3131
3132
3133 OPENOLT_LOG(INFO, openolt_log_id, "Delete request received for group %d\n", group_id);
3134
3135 if (group_id >= 0) {
3136 key.id = group_id;
3137 } else {
3138 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
3139 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
3140 }
3141
3142 /* init the BAL INIT API */
3143 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3144
3145 OPENOLT_LOG(DEBUG, openolt_log_id, "Checking if group %d exists...\n",group_id);
3146
3147 // CONFIGURE GROUP MEMBERS
3148 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
3149 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
3150
3151 if (err != BCM_ERR_OK) {
3152 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
3153 return bcm_to_grpc_err(err, "Error in querying group");
3154 }
3155
3156 if (grp_cfg_obj.data.state != BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
3157 OPENOLT_LOG(DEBUG, openolt_log_id, "Group %d exists. Will be deleted.\n",group_id);
3158 err = bcmolt_cfg_clear(dev_id, &(grp_cfg_obj.hdr));
3159 if (err != BCM_ERR_OK) {
3160 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d cannot be deleted err = %s (%d).\n", group_id, bcmos_strerror(err), err);
3161 return bcm_to_grpc_err(err, "Failed to delete group");;
3162 }
3163 } else {
3164 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d does not exist.\n", group_id);
3165 return Status(grpc::StatusCode::NOT_FOUND, "Group not found");
3166 }
3167
3168 OPENOLT_LOG(INFO, openolt_log_id, "Group %d has been deleted successfully.\n", group_id);
3169 return Status::OK;
Jason Huang1d9cfce2020-05-20 22:58:47 +08003170}
3171
Girish Gowdra252f4972020-09-07 21:24:01 -07003172Status GetLogicalOnuDistanceZero_(uint32_t intf_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003173 bcmos_errno err = BCM_ERR_OK;
3174 uint32_t mld = 0;
3175 double LD0;
3176
3177 err = getOnuMaxLogicalDistance(intf_id, &mld);
3178 if (err != BCM_ERR_OK) {
3179 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3180 }
3181
3182 LD0 = LOGICAL_DISTANCE(mld*1000, MINIMUM_ONU_RESPONSE_RANGING_TIME, ONU_BIT_TRANSMISSION_DELAY);
3183 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance zero is %f, (PON %d)\n", LD0, intf_id);
3184 response->set_intf_id(intf_id);
3185 response->set_logical_onu_distance_zero(LD0);
3186
3187 return Status::OK;
3188}
3189
Girish Gowdra252f4972020-09-07 21:24:01 -07003190Status GetLogicalOnuDistance_(uint32_t intf_id, uint32_t onu_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003191 bcmos_errno err = BCM_ERR_OK;
3192 bcmolt_itu_onu_params itu = {};
3193 bcmolt_onu_cfg onu_cfg;
3194 bcmolt_onu_key onu_key = {};
3195 uint32_t mld = 0;
3196 double LDi;
3197
3198 onu_key.pon_ni = intf_id;
3199 onu_key.onu_id = onu_id;
3200
3201 err = getOnuMaxLogicalDistance(intf_id, &mld);
3202 if (err != BCM_ERR_OK) {
3203 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3204 }
3205
3206 /* Initialize the API struct. */
3207 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
3208 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
3209 BCMOLT_FIELD_SET_PRESENT(&itu, itu_onu_params, ranging_time);
3210 BCMOLT_FIELD_SET(&onu_cfg.data, onu_cfg_data, itu, itu);
3211 #ifdef TEST_MODE
3212 // It is impossible to mock the setting of onu_cfg.data.onu_state because
3213 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
3214 // set the onu_cfg.data.onu_state. So a new stub function is created and address
3215 // of onu_cfg is passed. This is one-of case where we need to add test specific
3216 // code in production code.
3217 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
3218 #else
3219 /* Call API function. */
3220 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
3221 #endif
3222 if (err != BCM_ERR_OK) {
3223 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);
3224 return bcm_to_grpc_err(err, "Failed to retrieve ONU ranging time");
3225 }
3226
3227 if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_ACTIVE) {
3228 OPENOLT_LOG(ERROR, openolt_log_id, "ONU is not yet activated (PON %d, ONU id %d)\n", intf_id, onu_id);
3229 return bcm_to_grpc_err(BCM_ERR_PARM, "ONU is not yet activated\n");
3230 }
3231
3232 LDi = LOGICAL_DISTANCE(mld*1000, onu_cfg.data.itu.ranging_time, ONU_BIT_TRANSMISSION_DELAY);
3233 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance is %f, (PON %d, ONU id %d)\n", LDi, intf_id, onu_id);
3234 response->set_intf_id(intf_id);
3235 response->set_onu_id(onu_id);
3236 response->set_logical_onu_distance(LDi);
3237
3238 return Status::OK;
3239}
Burak Gurdag74e3ab82020-12-17 13:35:06 +00003240
3241Status GetOnuStatistics_(uint32_t intf_id, uint32_t onu_id, openolt::OnuStatistics* onu_stats) {
3242 bcmos_errno err;
3243
3244 err = get_onu_statistics((bcmolt_interface_id)intf_id, (bcmolt_onu_id)onu_id, onu_stats);
3245
3246 if (err != BCM_ERR_OK) {
3247 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));
3248 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of ONU statistics failed");
3249 }
3250
3251 OPENOLT_LOG(INFO, openolt_log_id, "retrieved ONU statistics for PON ID = %d, ONU ID = %d\n", (int)intf_id, (int)onu_id);
3252 return Status::OK;
3253}
3254
3255Status GetGemPortStatistics_(uint32_t intf_id, uint32_t gemport_id, openolt::GemPortStatistics* gemport_stats) {
3256 bcmos_errno err;
3257
3258 err = get_gemport_statistics((bcmolt_interface_id)intf_id, (bcmolt_gem_port_id)gemport_id, gemport_stats);
3259
3260 if (err != BCM_ERR_OK) {
3261 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));
3262 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of GEMPORT statistics failed");
3263 }
3264
3265 OPENOLT_LOG(INFO, openolt_log_id, "retrieved GEMPORT statistics for PON ID = %d, GEMPORT ID = %d\n", (int)intf_id, (int)gemport_id);
3266 return Status::OK;
3267}