blob: a987540c612a9d55f63041a102afd337c89e992e [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;
430 for (int i = 0; i < NumPonIf_(); i++) {
431 status = DisablePonIf_(i);
432 if (!status.ok()) {
433 failedCount+=1;
434 BCM_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", i);
435 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400436 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400437 if (failedCount == 0) {
438 state.deactivate();
Girish Gowdra252f4972020-09-07 21:24:01 -0700439 ::openolt::Indication ind;
440 ::openolt::OltIndication* olt_ind = new ::openolt::OltIndication;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400441 olt_ind->set_oper_state("down");
442 ind.set_allocated_olt_ind(olt_ind);
443 BCM_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
444 oltIndQ.push(ind);
445 return Status::OK;
446 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000447 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400448 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to disable olt ,all the PON ports are still in enabled state");
449 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400450
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400451 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 -0400452}
453
454Status Reenable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400455 Status status;
456 int failedCount = 0;
457 for (int i = 0; i < NumPonIf_(); i++) {
458 status = EnablePonIf_(i);
459 if (!status.ok()) {
460 failedCount+=1;
461 BCM_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", i);
462 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400463 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000464 if (failedCount == 0) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400465 state.activate();
Girish Gowdra252f4972020-09-07 21:24:01 -0700466 ::openolt::Indication ind;
467 ::openolt::OltIndication* olt_ind = new ::openolt::OltIndication;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400468 olt_ind->set_oper_state("up");
469 ind.set_allocated_olt_ind(olt_ind);
470 BCM_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
471 oltIndQ.push(ind);
472 return Status::OK;
473 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000474 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400475 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to re-enable olt ,all the PON ports are still in disabled state");
476 }
477 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 +0000478}
479
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000480inline uint64_t get_flow_status(uint16_t flow_id, uint16_t flow_type, uint16_t data_id) {
481 bcmos_errno err;
482 bcmolt_flow_key flow_key;
483 bcmolt_flow_cfg flow_cfg;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400484
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000485 flow_key.flow_id = flow_id;
486 flow_key.flow_type = (bcmolt_flow_type)flow_type;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400487
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000488 BCMOLT_CFG_INIT(&flow_cfg, flow, flow_key);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400489
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000490 switch (data_id) {
491 case ONU_ID: //onu_id
492 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, onu_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500493 #ifdef TEST_MODE
494 // It is impossible to mock the setting of flow_cfg.data.state because
495 // the actual bcmolt_cfg_get passes the address of flow_cfg.hdr and we cannot
496 // set the flow_cfg.data. So a new stub function is created and address
497 // of flow_cfg is passed. This is one-of case where we need to add test specific
498 // code in production code.
499 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
500 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000501 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500502 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000503 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500504 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get onu_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000505 return err;
506 }
507 return flow_cfg.data.onu_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400508 case FLOW_TYPE:
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500509 #ifdef TEST_MODE
510 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
511 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000512 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500513 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000514 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500515 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get flow_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000516 return err;
517 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400518 return flow_cfg.key.flow_type;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000519 case SVC_PORT_ID: //svc_port_id
520 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, svc_port_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500521 #ifdef TEST_MODE
522 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
523 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000524 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500525 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000526 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500527 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 +0000528 return err;
529 }
530 return flow_cfg.data.svc_port_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400531 case PRIORITY:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000532 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, priority);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500533 #ifdef TEST_MODE
534 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
535 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000536 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500537 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000538 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500539 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get priority, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000540 return err;
541 }
542 return flow_cfg.data.priority;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400543 case COOKIE: //cookie
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000544 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, cookie);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500545 #ifdef TEST_MODE
546 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
547 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000548 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500549 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000550 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500551 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get cookie, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000552 return err;
553 }
554 return flow_cfg.data.cookie;
555 case INGRESS_INTF_TYPE: //ingress intf_type
556 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500557 #ifdef TEST_MODE
558 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
559 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000560 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500561 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000562 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500563 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 +0000564 return err;
565 }
566 return flow_cfg.data.ingress_intf.intf_type;
567 case EGRESS_INTF_TYPE: //egress intf_type
568 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500569 #ifdef TEST_MODE
570 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
571 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000572 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500573 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000574 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500575 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 +0000576 return err;
577 }
578 return flow_cfg.data.egress_intf.intf_type;
579 case INGRESS_INTF_ID: //ingress intf_id
580 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500581 #ifdef TEST_MODE
582 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
583 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000584 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500585 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000586 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500587 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 +0000588 return err;
589 }
590 return flow_cfg.data.ingress_intf.intf_id;
591 case EGRESS_INTF_ID: //egress intf_id
592 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500593 #ifdef TEST_MODE
594 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
595 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000596 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500597 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000598 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500599 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 +0000600 return err;
601 }
602 return flow_cfg.data.egress_intf.intf_id;
603 case CLASSIFIER_O_VID:
604 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500605 #ifdef TEST_MODE
606 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
607 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000608 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500609 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000610 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500611 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 +0000612 return err;
613 }
614 return flow_cfg.data.classifier.o_vid;
615 case CLASSIFIER_O_PBITS:
616 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500617 #ifdef TEST_MODE
618 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
619 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000620 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500621 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000622 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500623 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 +0000624 return err;
625 }
626 return flow_cfg.data.classifier.o_pbits;
627 case CLASSIFIER_I_VID:
628 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500629 #ifdef TEST_MODE
630 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
631 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000632 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500633 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000634 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500635 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 +0000636 return err;
637 }
638 return flow_cfg.data.classifier.i_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400639 case CLASSIFIER_I_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000640 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500641 #ifdef TEST_MODE
642 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
643 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000644 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500645 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000646 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500647 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 +0000648 return err;
649 }
650 return flow_cfg.data.classifier.i_pbits;
651 case CLASSIFIER_ETHER_TYPE:
652 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500653 #ifdef TEST_MODE
654 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
655 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000656 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500657 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000658 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500659 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 +0000660 return err;
661 }
662 return flow_cfg.data.classifier.ether_type;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400663 case CLASSIFIER_IP_PROTO:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000664 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500665 #ifdef TEST_MODE
666 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
667 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000668 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500669 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000670 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500671 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 +0000672 return err;
673 }
674 return flow_cfg.data.classifier.ip_proto;
675 case CLASSIFIER_SRC_PORT:
676 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500677 #ifdef TEST_MODE
678 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
679 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000680 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500681 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000682 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500683 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 +0000684 return err;
685 }
686 return flow_cfg.data.classifier.src_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400687 case CLASSIFIER_DST_PORT:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000688 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500689 #ifdef TEST_MODE
690 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
691 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000692 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500693 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000694 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500695 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 +0000696 return err;
697 }
698 return flow_cfg.data.classifier.dst_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400699 case CLASSIFIER_PKT_TAG_TYPE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000700 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500701 #ifdef TEST_MODE
702 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
703 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000704 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500705 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000706 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500707 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 +0000708 return err;
709 }
710 return flow_cfg.data.classifier.pkt_tag_type;
711 case EGRESS_QOS_TYPE:
712 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500713 #ifdef TEST_MODE
714 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
715 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000716 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500717 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000718 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500719 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 +0000720 return err;
721 }
722 return flow_cfg.data.egress_qos.type;
723 case EGRESS_QOS_QUEUE_ID:
724 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500725 #ifdef TEST_MODE
726 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
727 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000728 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500729 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000730 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500731 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 +0000732 return err;
733 }
734 switch (flow_cfg.data.egress_qos.type) {
735 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE:
736 return flow_cfg.data.egress_qos.u.fixed_queue.queue_id;
737 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE:
738 return flow_cfg.data.egress_qos.u.tc_to_queue.tc_to_queue_id;
739 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC:
740 return flow_cfg.data.egress_qos.u.pbit_to_tc.tc_to_queue_id;
741 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE:
742 return flow_cfg.data.egress_qos.u.priority_to_queue.tm_q_set_id;
743 case BCMOLT_EGRESS_QOS_TYPE_NONE:
744 default:
745 return -1;
746 }
747 case EGRESS_QOS_TM_SCHED_ID:
748 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500749 #ifdef TEST_MODE
750 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
751 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000752 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500753 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000754 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500755 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 +0000756 return err;
757 }
758 return flow_cfg.data.egress_qos.tm_sched.id;
759 case ACTION_CMDS_BITMASK:
760 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500761 #ifdef TEST_MODE
762 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
763 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000764 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500765 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000766 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500767 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 +0000768 return err;
769 }
770 return flow_cfg.data.action.cmds_bitmask;
771 case ACTION_O_VID:
772 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500773 #ifdef TEST_MODE
774 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
775 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000776 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500777 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000778 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500779 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 +0000780 return err;
781 }
782 return flow_cfg.data.action.o_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400783 case ACTION_O_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000784 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500785 #ifdef TEST_MODE
786 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
787 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000788 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500789 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000790 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500791 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 +0000792 return err;
793 }
794 return flow_cfg.data.action.o_pbits;
795 case ACTION_I_VID:
796 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500797 #ifdef TEST_MODE
798 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
799 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000800 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500801 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000802 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500803 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 +0000804 return err;
805 }
806 return flow_cfg.data.action.i_vid;
807 case ACTION_I_PBITS:
808 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500809 #ifdef TEST_MODE
810 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
811 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000812 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500813 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000814 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500815 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 +0000816 return err;
817 }
818 return flow_cfg.data.action.i_pbits;
819 case STATE:
820 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, state);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500821 #ifdef TEST_MODE
822 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
823 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000824 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500825 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000826 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500827 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get state, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000828 return err;
829 }
830 return flow_cfg.data.state;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000831 case GROUP_ID:
832 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, group_id);
833 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
834 if (err) {
835 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get group_id, err = %s\n",bcmos_strerror(err));
836 return err;
837 }
838 return flow_cfg.data.group_id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000839 default:
840 return BCM_ERR_INTERNAL;
841 }
842
843 return err;
844}
845
846Status EnablePonIf_(uint32_t intf_id) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400847 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000848 bcmolt_pon_interface_cfg interface_obj;
849 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
850 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
851 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530852 bcmolt_status los_status;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000853
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530854 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000855 if (err == BCM_ERR_OK) {
856 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800857 OPENOLT_LOG(WARNING, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000858 return Status::OK;
859 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400860 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000861 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
862 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
863 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
864 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.interval, 5000);
865 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.onu_post_discovery_mode,
Girish Gowdra24297032020-03-23 12:32:37 -0700866 BCMOLT_ONU_POST_DISCOVERY_MODE_NONE);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000867 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.los, true);
868 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.onu_alarms, true);
869 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.tiwi, true);
870 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.ack_timeout, true);
871 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.sfi, true);
872 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.loki, true);
Burak Gurdag5e587792020-05-06 14:58:02 +0000873
874 // On GPON, power level mode is not set to its default value (i.e. 0) as documented in Broadcom documentation.
875 // Instead, it is set to 2 which means -6 dbM attenuation. Therefore, we explicitly set it to the default value below.
876 if (board_technology == "GPON") {
877 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.pls_maximum_allocation_size, BCMOLT_PON_POWER_LEVEL_PLS_MAXIMUM_ALLOCATION_SIZE_DEFAULT);
878 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.mode, BCMOLT_PON_POWER_LEVEL_MODE_DEFAULT);
879 }
880
kesavandc1f2db92020-08-31 15:32:06 +0530881 //Enable AES Encryption
882 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.key_exchange, BCMOLT_CONTROL_STATE_ENABLE);
883 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.authentication, BCMOLT_CONTROL_STATE_ENABLE);
884 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.fail_due_to_authentication_failure, BCMOLT_CONTROL_STATE_ENABLE);
885
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000886 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
887 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
888
889 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
890 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500891 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 +0000892 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
893 }
894 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
895 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500896 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 +0000897 return bcm_to_grpc_err(err, "Failed to enable PON interface");
898 }
899 else {
900 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
901 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
902 CreateDefaultSched(intf_id, downstream);
903 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400904 }
905
906 return Status::OK;
907}
908
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500909Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000910 bcmos_errno err;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400911 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000912 bcmolt_device_key dev_key = { };
913 bcmolt_olt_cfg olt_cfg = { };
914 bcmolt_olt_key olt_key = { };
915 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
916 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500917
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000918 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
919 topo.topology_maps.arr = &topo_map[0];
920 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
921 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
922 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400923 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000924 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400925 #ifdef TEST_MODE
926 // It is impossible to mock the setting of olt_cfg.data.bal_state because
927 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
928 // set the olt_cfg.data.topology. So a new stub function is created and address
929 // of olt_cfg is passed. This is one-of case where we need to test add specific
930 // code in production code.
931 err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
932 #else
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000933 err = bcmolt_cfg_get_mult_retry(dev_id, &olt_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400934 #endif
935 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500936 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 +0000937 return bcm_to_grpc_err(err, "cfg: Failed to query OLT topology");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500938 }
939
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000940 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
941 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500942
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400943 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
944 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000945 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500946
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000947 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
948 num_of_nni_ports,
949 num_of_pon_ports,
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400950 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500951
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000952 uint32_t num_failed_cfg_gets = 0;
Jason Huang09b73ea2020-01-08 17:52:05 +0800953 static std::string openolt_version = firmware_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000954 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
955 dev_key.device_id = devid;
956 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
957 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
958 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
959 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000960 err = bcmolt_cfg_get_mult_retry(dev_id, &dev_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400961 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500962 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 +0000963 num_failed_cfg_gets++;
964 continue;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000965 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500966
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000967 std::string bal_version;
968 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
969 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
970 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
Jason Huang09b73ea2020-01-08 17:52:05 +0800971 firmware_version = "BAL." + bal_version + "__" + openolt_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000972
973 switch(dev_cfg.data.system_mode) {
974 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
975 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
976 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
977 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
978 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
979 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
980 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
981 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
982 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
983 case 20: board_technology = MIXED_TECH; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,MIXED_TECH); break;
984 }
985
986 switch(dev_cfg.data.chip_family) {
Jason Huang09b73ea2020-01-08 17:52:05 +0800987 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X: chip_family = "Maple"; break;
988 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X: chip_family = "Aspen"; break;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000989 }
990
Jason Huang09b73ea2020-01-08 17:52:05 +0800991 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s, family: %s, board_technology: %s\n",
992 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 +0000993
994 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500995 }
996
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000997 /* 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 +0000998 only the devices that retured success*/
999 if (num_failed_cfg_gets == BCM_MAX_DEVS_PER_LINE_CARD) {
1000 OPENOLT_LOG(ERROR, openolt_log_id, "device: Query of all the devices failed\n");
1001 return bcm_to_grpc_err(err, "device: All devices failed query");
1002 }
1003
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001004 return Status::OK;
1005}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001006
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001007Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001008 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001009 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
1010 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
1011 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001012
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001013 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001014 if (err == BCM_ERR_OK) {
1015 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001016 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001017 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1018 CreateDefaultSched(intf_id, upstream);
1019 CreateDefaultQueue(intf_id, upstream);
1020 return Status::OK;
1021 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1022 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
1023 return Status::OK;
1024 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001025 }
1026
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001027 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
1028 if (set_state) {
1029 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1030 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1031 } else {
1032 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1033 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1034 }
1035 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
1036 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001037 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err = %s\n",
1038 (set_state)?"enable":"disable", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001039 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
1040 }
1041 else {
1042 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
1043 if (set_state) {
1044 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1045 CreateDefaultSched(intf_id, upstream);
1046 CreateDefaultQueue(intf_id, upstream);
1047 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001048 }
1049
1050 return Status::OK;
1051}
1052
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001053Status DisablePonIf_(uint32_t intf_id) {
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001054 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001055 bcmolt_pon_interface_cfg interface_obj;
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001056 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1057 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001058
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001059 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
1060 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1061 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_DISABLE);
1062
1063 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1064 if (err != BCM_ERR_OK) {
1065 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable discovery of onu, PON interface %d, err %d\n", intf_id, err);
1066 return bcm_to_grpc_err(err, "Failed to disable discovery of onu");
1067 }
1068
1069 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1070 operation, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1071
1072 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1073 if (err != BCM_ERR_OK) {
1074 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 -04001075 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001076 }
1077
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001078 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled PON interface: %d\n", intf_id);
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001079 return Status::OK;
1080}
1081
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001082Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
kesavandc1f2db92020-08-31 15:32:06 +05301083 const char *vendor_id, const char *vendor_specific, uint32_t pir, bool omcc_encryption_mode) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001084 bcmos_errno err = BCM_ERR_OK;
1085 bcmolt_onu_cfg onu_cfg;
1086 bcmolt_onu_key onu_key;
1087 bcmolt_serial_number serial_number; /**< ONU serial number */
1088 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001089
Girish Gowdra24297032020-03-23 12:32:37 -07001090 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1091 bcmolt_onu_state onu_state;
1092
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001093 onu_key.onu_id = onu_id;
1094 onu_key.pon_ni = intf_id;
1095 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1096 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Girish Gowdra24297032020-03-23 12:32:37 -07001097#ifdef TEST_MODE
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001098 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1099 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1100 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1101 // of onu_cfg is passed. This is one-of case where we need to add test specific
1102 // code in production code.
1103 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Girish Gowdra24297032020-03-23 12:32:37 -07001104#else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001105 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Girish Gowdra24297032020-03-23 12:32:37 -07001106#endif
1107 OPENOLT_LOG(INFO, openolt_log_id, "Activate ONU : old state = %d, current state = %d\n",
1108 onu_cfg.data.onu_old_state, onu_cfg.data.onu_state);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001109 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001110 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) {
1111 OPENOLT_LOG(INFO, openolt_log_id, "ONU is already in ACTIVE state, \
1112not processing this request for pon_intf=%d onu_id=%d\n", intf_id, onu_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001113 return Status::OK;
Girish Gowdra24297032020-03-23 12:32:37 -07001114 } else if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_NOT_CONFIGURED &&
1115 onu_cfg.data.onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1116 // We need the ONU to be in NOT_CONFIGURED or INACTIVE state to further process the request
1117 OPENOLT_LOG(ERROR, openolt_log_id, "ONU in an invalid state to process the request, \
1118state=%d pon_intf=%d onu_id=%d\n", onu_cfg.data.onu_state, intf_id, onu_id);
1119 return bcm_to_grpc_err(err, "Failed to activate ONU, invalid ONU state");
1120 }
1121 } else {
1122 // This should never happen. BAL GET should succeed for non-existant ONUs too. The state of such ONUs will be NOT_CONFIGURED
1123 OPENOLT_LOG(ERROR, openolt_log_id, "ONU state query failed pon_intf=%d onu_id=%d\n", intf_id, onu_id);
1124 return bcm_to_grpc_err(err, "onu get failed");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001125 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001126
Girish Gowdra24297032020-03-23 12:32:37 -07001127 // If the ONU is not configured at all we need to first configure it
1128 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_NOT_CONFIGURED) {
1129 OPENOLT_LOG(INFO, openolt_log_id, "Configuring ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001130vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Girish Gowdra24297032020-03-23 12:32:37 -07001131 vendor_specific_to_str(vendor_specific).c_str(), pir);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001132
Girish Gowdra24297032020-03-23 12:32:37 -07001133 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1134 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1135 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1136 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1137 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1138 /*set burst and data profiles to fec disabled*/
1139 if (board_technology == "XGS-PON") {
1140 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1141 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1142 } else if (board_technology == "GPON") {
1143 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1144 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1145 }
1146 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1147 if (err != BCM_ERR_OK) {
1148 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to configure ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
1149 return bcm_to_grpc_err(err, "Failed to configure ONU");
1150 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001151 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001152
Burak Gurdaga0523592021-02-24 15:17:47 +00001153// TODO: MOVE THIS TO A NEW METHOD
kesavandc1f2db92020-08-31 15:32:06 +05301154 if (omcc_encryption_mode == true) {
1155 // set the encryption mode for omci port id
1156 bcmolt_itupon_gem_cfg gem_cfg;
1157 bcmolt_itupon_gem_key key = {};
1158 bcmolt_gem_port_configuration configuration = {};
1159 key.pon_ni = intf_id;
1160 key.gem_port_id = onu_id;
1161 bcmolt_control_state encryption_mode;
1162 encryption_mode = BCMOLT_CONTROL_STATE_ENABLE;
1163 BCMOLT_CFG_INIT(&gem_cfg, itupon_gem, key);
1164 BCMOLT_FIELD_SET(&gem_cfg.data, itupon_gem_cfg_data, encryption_mode, encryption_mode);
1165 err = bcmolt_cfg_set(dev_id, &gem_cfg.hdr);
1166 if(err != BCM_ERR_OK) {
Burak Gurdaga0523592021-02-24 15:17:47 +00001167 OPENOLT_LOG(ERROR, openolt_log_id, "failed to configure omci gem_port encryption mode = %d\n", onu_id);
kesavandc1f2db92020-08-31 15:32:06 +05301168 return bcm_to_grpc_err(err, "Access_Control set ITU PON OMCI Gem port failed");
1169 }
1170 }
Girish Gowdra24297032020-03-23 12:32:37 -07001171 // Now that the ONU is configured, move the ONU to ACTIVE state
1172 memset(&onu_cfg, 0, sizeof(bcmolt_onu_cfg));
1173 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1174 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1175 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
1176 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
1177 onu_state, BCMOLT_ONU_OPERATION_ACTIVE);
1178 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001179 if (err != BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001180 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 +00001181 return bcm_to_grpc_err(err, "Failed to activate ONU");
1182 }
Girish Gowdra24297032020-03-23 12:32:37 -07001183 // ONU will eventually get activated after we have submitted the operation request. The adapter will receive an asynchronous
1184 // ONU_ACTIVATION_COMPLETED_INDICATION
1185
1186 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 +00001187
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001188 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001189}
1190
Jonathan Davis70c21812018-07-19 15:32:10 -04001191Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1192 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001193 bcmos_errno err = BCM_ERR_OK;
1194 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1195 bcmolt_onu_cfg onu_cfg;
1196 bcmolt_onu_key onu_key; /**< Object key. */
1197 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001198
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001199 onu_key.onu_id = onu_id;
1200 onu_key.pon_ni = intf_id;
1201 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1202 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001203 #ifdef TEST_MODE
1204 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1205 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1206 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1207 // of onu_cfg is passed. This is one-of case where we need to add test specific
1208 // code in production code.
1209 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001210 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001211 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001212 #endif
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301213 onu_state = onu_cfg.data.onu_state;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001214 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001215 switch (onu_state) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001216 case BCMOLT_ONU_STATE_ACTIVE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001217 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001218 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001219 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1220 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1221 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001222 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 +00001223 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1224 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301225 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 +00001226 break;
1227 }
Jonathan Davis70c21812018-07-19 15:32:10 -04001228 }
1229
1230 return Status::OK;
1231}
1232
1233Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001234 const char *vendor_id, const char *vendor_specific) {
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301235 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301236 bcmolt_onu_state onu_state;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001237
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001238 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 -05001239 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1240
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001241 // Need to deactivate before removing it (BAL rules)
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001242 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301243
1244 err = get_onu_status((bcmolt_interface)intf_id, onu_id, &onu_state);
1245 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001246 if (onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1247 OPENOLT_LOG(INFO, openolt_log_id, "waiting for onu deactivate complete response: intf_id=%d, onu_id=%d\n",
1248 intf_id, onu_id);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301249 err = wait_for_onu_deactivate_complete(intf_id, onu_id);
1250 if (err) {
1251 OPENOLT_LOG(ERROR, openolt_log_id, "failed to delete onu intf_id %d, onu_id %d\n",
1252 intf_id, onu_id);
1253 return bcm_to_grpc_err(err, "Failed to delete ONU");
1254 }
1255 }
Girish Gowdra24297032020-03-23 12:32:37 -07001256 else {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301257 OPENOLT_LOG(INFO, openolt_log_id, "Onu is Inactive, onu_id: %d, not waiting for onu deactivate complete response\n",
1258 intf_id);
1259 }
1260 }
1261 else {
1262 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch Onu status, onu_id = %d, intf_id = %d, err = %s\n",
1263 onu_id, intf_id, bcmos_strerror(err));
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301264 return bcm_to_grpc_err(err, "Failed to delete ONU");
1265 }
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001266
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001267 bcmolt_onu_cfg cfg_obj;
1268 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001269
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001270 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 -04001271 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001272
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001273 key.onu_id = onu_id;
1274 key.pon_ni = intf_id;
1275 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001276
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301277 err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001278 if (err != BCM_ERR_OK)
1279 {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001280 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 -04001281 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1282 }
1283
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301284 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 +00001285 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001286}
1287
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001288#define MAX_CHAR_LENGTH 20
1289#define MAX_OMCI_MSG_LENGTH 44
1290Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001291 bcmolt_bin_str buf = {};
1292 bcmolt_onu_cpu_packets omci_cpu_packets;
1293 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001294
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001295 key.pon_ni = intf_id;
1296 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001297
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001298 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1299 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1300 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001301
1302 // ???
1303 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1304 buf.len = MAX_OMCI_MSG_LENGTH;
1305 } else {
1306 buf.len = pkt.size()/2;
1307 }
1308
1309 /* Send the OMCI packet using the BAL remote proxy API */
1310 uint16_t idx1 = 0;
1311 uint16_t idx2 = 0;
1312 uint8_t arraySend[buf.len];
1313 char str1[MAX_CHAR_LENGTH];
1314 char str2[MAX_CHAR_LENGTH];
1315 memset(&arraySend, 0, buf.len);
1316
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001317 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1318 sprintf(str1,"%c", pkt[idx1]);
1319 sprintf(str2,"%c", pkt[++idx1]);
1320 strcat(str1,str2);
1321 arraySend[idx2] = strtol(str1, NULL, 16);
1322 }
1323
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001324 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1325 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001326
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001327 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1328 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1329 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001330
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001331 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001332 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001333 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 +00001334 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001335 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001336 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 -05001337 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001338 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001339 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001340
1341 return Status::OK;
1342}
1343
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001344Status 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 +00001345 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1346 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1347 bcmolt_bin_str buf = {};
1348 bcmolt_gem_port_id gem_port_id_array[1];
1349 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001350
Craig Lutgen967a1d02018-11-27 10:41:51 -06001351 if (port_no > 0) {
1352 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001353 if (gemport_id == 0) {
1354 bcmos_fastlock_lock(&data_lock);
1355 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1356 // Pick any flow that is mapped with the same port_no.
1357 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1358 if (it != port_to_flows.end() && !it->second.empty()) {
1359 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1360 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1361 if (fit != flowid_to_gemport.end()) {
1362 found = true;
1363 gemport_id = fit->second;
1364 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001365 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001366 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001367
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001368 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001369 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 -08001370 onu_id, port_no, intf_id);
1371 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1372 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001373 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 -08001374 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001375 }
1376
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001377 gem_port_id_array[0] = gemport_id;
1378 gem_port_list.len = 1;
1379 gem_port_list.arr = gem_port_id_array;
1380 buf.len = pkt.size();
1381 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1382 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1383
1384 /* init the API struct */
1385 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1386 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1387 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1388 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1389 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1390
1391 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1392 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1393
1394 /* call API */
1395 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001396 }
1397 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001398 //TODO: Port No is 0, it is coming sender requirement.
1399 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1400 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001401 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001402 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001403
1404 return Status::OK;
1405}
1406
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001407Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001408 bcmolt_flow_key key = {}; /* declare key */
1409 bcmolt_bin_str buffer = {};
1410 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001411
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001412 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
Girish Gowdra252f4972020-09-07 21:24:01 -07001413 bcmolt_flow_id flow_id = INVALID_FLOW_ID;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001414
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001415 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1416 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1417 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1418 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1419 key.flow_id = flow_id;
1420 else {
Jason Huang09b73ea2020-01-08 17:52:05 +08001421 if (flow_id_counters) {
1422 std::map<flow_pair, int>::iterator it;
1423 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1424 int flow_index = it->first.first;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001425 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1426 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1427 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1428 key.flow_id = flow_index;
1429 break;
1430 }
1431 }
1432 }
1433 else {
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001434 OPENOLT_LOG(ERROR, openolt_log_id, "no flow id found for uplink packetout\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001435 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1436 }
1437 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001438
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001439 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001440
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001441 /* Initialize the API struct. */
1442 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001443
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001444 buffer.len = pkt.size();
1445 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1446 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1447 if (buffer.arr == NULL) {
1448 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1449 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1450 }
1451 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1452
1453 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1454 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001455 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 -05001456 return bcm_to_grpc_err(BCM_ERR_SYSCALL_ERR, "Error sending packets via nni port");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001457 } else {
1458 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1459 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001460
1461 return Status::OK;
1462}
Girish Gowdra252f4972020-09-07 21:24:01 -07001463
Burak Gurdaga0523592021-02-24 15:17:47 +00001464bool get_aes_flag_for_gem_port(const google::protobuf::Map<unsigned int, bool> &gemport_to_aes, uint32_t gemport_id) {
1465 bool aes_flag = false;
1466 for (google::protobuf::Map<unsigned int, bool>::const_iterator it=gemport_to_aes.begin(); it!=gemport_to_aes.end(); it++) {
1467 if (it->first == gemport_id) {
1468 aes_flag = it->second;
1469 break;
1470 }
1471 }
1472 return aes_flag;
1473}
1474
Girish Gowdra252f4972020-09-07 21:24:01 -07001475Status FlowAddWrapper_(const ::openolt::Flow* request) {
1476
1477 int32_t access_intf_id = request->access_intf_id();
1478 int32_t onu_id = request->onu_id();
1479 int32_t uni_id = request->uni_id();
1480 uint32_t port_no = request->port_no();
1481 uint64_t voltha_flow_id = request->flow_id();
1482 uint64_t symmetric_voltha_flow_id = request->symmetric_flow_id();
1483 const std::string flow_type = request->flow_type();
1484 int32_t alloc_id = request->alloc_id();
1485 int32_t network_intf_id = request->network_intf_id();
1486 int32_t gemport_id = request->gemport_id();
1487 const ::openolt::Classifier& classifier = request->classifier();
1488 const ::openolt::Action& action = request->action();
1489 int32_t priority = request->priority();
1490 uint64_t cookie = request->cookie();
1491 int32_t group_id = request->group_id();
1492 uint32_t tech_profile_id = request->tech_profile_id();
1493 bool replicate_flow = request->replicate_flow();
1494 const google::protobuf::Map<unsigned int, unsigned int> &pbit_to_gemport = request->pbit_to_gemport();
Burak Gurdaga0523592021-02-24 15:17:47 +00001495 const google::protobuf::Map<unsigned int, bool> &gemport_to_aes = request->gemport_to_aes();
Girish Gowdra252f4972020-09-07 21:24:01 -07001496 uint16_t flow_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001497 bool enable_encryption;
Girish Gowdra252f4972020-09-07 21:24:01 -07001498
1499 // The intf_id variable defaults to access(PON) interface ID.
1500 // For trap-from-nni flow where access interface ID is not valid , change it to NNI interface ID
1501 // This intf_id identifies the pool from which we get the flow_id
1502 uint32_t intf_id = access_intf_id;
1503 if (onu_id < 1) {
1504 onu_id = 1;
1505 }
1506 if (access_intf_id < 0) {
1507 intf_id = network_intf_id;
1508 }
1509
1510 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)
1511 // This is the case of voltha_flow_id (not symmetric_voltha_flow_id)
1512 if (is_voltha_flow_installed(voltha_flow_id)) {
1513 OPENOLT_LOG(INFO, openolt_log_id, "voltha_flow_id=%lu, already installed\n", voltha_flow_id);
1514 return ::Status(grpc::StatusCode::ALREADY_EXISTS, "voltha-flow-already-installed");
1515 }
1516
Girish Gowdra252f4972020-09-07 21:24:01 -07001517 // This is the case of symmetric_voltha_flow_id
1518 // If symmetric_voltha_flow_id is available and valid in the Flow message,
1519 // check if it is installed, and use the corresponding device_flow_id
1520 if (symmetric_voltha_flow_id > 0 && is_voltha_flow_installed(symmetric_voltha_flow_id)) { // symmetric flow found
1521 OPENOLT_LOG(INFO, openolt_log_id, "symmetric flow and the symmetric flow is installed\n");
1522 const device_flow_params *dev_fl_symm_params;
1523 dev_fl_symm_params = get_device_flow_params(symmetric_voltha_flow_id);
1524 if (dev_fl_symm_params == NULL) {
1525 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)
1526 return ::Status(grpc::StatusCode::INTERNAL, "symmetric-flow-details-not-found");
1527 }
1528
1529 if (!replicate_flow) { // No flow replication
1530 flow_id = dev_fl_symm_params[0].flow_id;
1531 gemport_id = dev_fl_symm_params[0].gemport_id; // overwrite the gemport with symmetric flow gemport
1532 // Should be same as what is coming in this request.
Burak Gurdaga0523592021-02-24 15:17:47 +00001533 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001534 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1535 cl.set_o_pbits(dev_fl_symm_params[0].pbit);
1536 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1537 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001538 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001539 if (st.error_code() == grpc::StatusCode::OK) {
1540 device_flow dev_fl;
1541 dev_fl.is_flow_replicated = false;
1542 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1543 dev_fl.voltha_flow_id = voltha_flow_id;
1544 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params));
1545 // update voltha flow to cache
1546 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1547 }
1548 return st;
1549 } else { // Flow to be replicated
1550 OPENOLT_LOG(INFO, openolt_log_id,"symmetric flow and replication is needed\n");
1551 for (uint8_t i=0; i<NUMBER_OF_REPLICATED_FLOWS; i++) {
1552 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1553 flow_id = dev_fl_symm_params[i].flow_id;
1554 gemport_id = dev_fl_symm_params[i].gemport_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001555 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001556 cl.set_o_pbits(dev_fl_symm_params[i].pbit);
1557 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdrade65ab42020-12-17 23:08:43 -08001558 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001559 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001560 if (st.error_code() != grpc::StatusCode::OK && st.error_code() != grpc::StatusCode::ALREADY_EXISTS) {
1561 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);
1562 // On failure remove any successfully replicated flows installed so far for the voltha_flow_id
1563 if (i > 0) {
1564 for (int8_t j = i-1; j >= 0; j--) {
1565 flow_id = dev_fl_symm_params[j].flow_id;
1566 FlowRemove_(flow_id, flow_type);
1567 }
1568 }
1569 return st;
1570 }
1571 }
1572 device_flow dev_fl;
1573 dev_fl.is_flow_replicated = true;
1574 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1575 dev_fl.voltha_flow_id = voltha_flow_id;
1576 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params)*NUMBER_OF_REPLICATED_FLOWS);
1577 // update voltha flow to cache
1578 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1579 }
1580 } else { // No symmetric flow found
1581 if (!replicate_flow) { // No flow replication
1582 OPENOLT_LOG(INFO, openolt_log_id, "not a symmetric flow and replication is not needed\n");
1583 flow_id = get_flow_id();
1584 if (flow_id == INVALID_FLOW_ID) {
1585 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocated flow id for voltha-flow-id=%lu\n", voltha_flow_id);
1586 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1587 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001588 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001589 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1590 flow_type, alloc_id, network_intf_id, gemport_id, classifier,
Burak Gurdaga0523592021-02-24 15:17:47 +00001591 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001592 if (st.error_code() == grpc::StatusCode::OK) {
1593 device_flow dev_fl;
1594 dev_fl.is_flow_replicated = false;
1595 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // Invalid
1596 dev_fl.voltha_flow_id = voltha_flow_id;
1597 dev_fl.params[0].flow_id = flow_id;
1598 dev_fl.params[0].gemport_id = gemport_id;
1599 dev_fl.params[0].pbit = classifier.o_pbits();
1600 // update voltha flow to cache
1601 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1602 } else {
1603 // Free the flow id on failure
1604 free_flow_id(flow_id);
1605 }
1606 return st;
1607 } else { // Flow to be replicated
1608 OPENOLT_LOG(INFO, openolt_log_id,"not a symmetric flow and replication is needed\n");
1609 if (pbit_to_gemport.size() != NUMBER_OF_PBITS) {
1610 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pbit-to-gemport map size=%lu", pbit_to_gemport.size())
1611 return ::Status(grpc::StatusCode::OUT_OF_RANGE, "pbit-to-gemport-map-len-invalid-for-flow-replication");
1612 }
1613 uint16_t flow_ids[NUMBER_OF_REPLICATED_FLOWS];
1614 device_flow dev_fl;
1615 if (get_flow_ids(NUMBER_OF_REPLICATED_FLOWS, flow_ids)) {
1616 uint8_t cnt = 0;
1617 dev_fl.is_flow_replicated = true;
1618 dev_fl.voltha_flow_id = voltha_flow_id;
1619 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // invalid
1620 for (google::protobuf::Map<unsigned int, unsigned int>::const_iterator it=pbit_to_gemport.begin(); it!=pbit_to_gemport.end(); it++) {
1621 dev_fl.params[cnt].flow_id = flow_ids[cnt];
1622 dev_fl.params[cnt].pbit = it->first;
1623 dev_fl.params[cnt].gemport_id = it->second;
1624
1625 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1626 flow_id = dev_fl.params[cnt].flow_id;
1627 gemport_id = dev_fl.params[cnt].gemport_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001628 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001629 cl.set_o_pbits(dev_fl.params[cnt].pbit);
1630 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1631 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001632 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001633 if (st.error_code() != grpc::StatusCode::OK) {
1634 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);
1635 // Remove any successfully replicated flows installed so far for the voltha_flow_id
1636 if (cnt > 0) {
1637 for (int8_t j = cnt-1; j >= 0; j--) {
1638 flow_id = dev_fl.params[j].flow_id;
1639 FlowRemove_(flow_id, flow_type);
1640 }
1641 }
1642 // Free up all the flow IDs on failure
1643 free_flow_ids(NUMBER_OF_REPLICATED_FLOWS, flow_ids);
1644 return st;
1645 }
1646 cnt++;
1647 }
1648 // On successful flow replication update voltha-flow-id to device-flow map to cache
1649 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1650 } else {
1651 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocate flow ids for replication voltha-flow-id=%lu\n", voltha_flow_id);
1652 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1653 }
1654 }
1655 }
1656
1657 return Status::OK;
1658}
1659
1660
Craig Lutgen967a1d02018-11-27 10:41:51 -06001661Status 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 +00001662 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001663 int32_t alloc_id, int32_t network_intf_id,
1664 int32_t gemport_id, const ::openolt::Classifier& classifier,
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001665 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie,
Burak Gurdaga0523592021-02-24 15:17:47 +00001666 int32_t group_id, uint32_t tech_profile_id, bool aes_enabled) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001667 bcmolt_flow_cfg cfg;
1668 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001669 int32_t o_vid = -1;
1670 bool single_tag = false;
1671 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001672 bcmolt_classifier c_val = { };
1673 bcmolt_action a_val = { };
1674 bcmolt_tm_queue_ref tm_val = { };
1675 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05001676 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001677
Jason Huang09b73ea2020-01-08 17:52:05 +08001678 OPENOLT_LOG(INFO, openolt_log_id, "flow add received for flow_id=%u, flow_type=%s\n", flow_id, flow_type.c_str());
1679
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001680 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001681 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001682 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001683 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001684 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001685 } else if (flow_type.compare(multicast) == 0) {
1686 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001687 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001688 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001689 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001690 }
1691
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001692 BCMOLT_CFG_INIT(&cfg, flow, key);
1693 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001694
Jason Huang09b73ea2020-01-08 17:52:05 +08001695 if (action.cmd().trap_to_host()) {
Girish Gowdra1935e6a2020-10-31 21:48:22 -07001696 Status resp = handle_acl_rule_install(onu_id, flow_id, gemport_id, flow_type, access_intf_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001697 network_intf_id, classifier);
Jason Huang09b73ea2020-01-08 17:52:05 +08001698 return resp;
1699 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001700
1701 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1702
1703 if (access_intf_id >= 0 && network_intf_id >= 0) {
1704 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1705 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1706 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08001707 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1708 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001709 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1710 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1711 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1712 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1713 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001714 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001715 } else {
1716 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
1717 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001718 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001719
Burak Gurdaga0523592021-02-24 15:17:47 +00001720 if (onu_id >= ONU_ID_START) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001721 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
1722 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001723 if (gemport_id >= GEM_PORT_ID_START) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001724 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
1725 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001726 if (gemport_id >= GEM_PORT_ID_START && port_no != 0) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001727 bcmos_fastlock_lock(&data_lock);
1728 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
1729 port_to_flows[port_no].insert(key.flow_id);
1730 flowid_to_gemport[key.flow_id] = gemport_id;
1731 }
1732 else
1733 {
1734 flowid_to_port[key.flow_id] = port_no;
1735 }
1736 bcmos_fastlock_unlock(&data_lock, 0);
1737 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001738
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001739 if (priority_value >= 0) {
1740 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
1741 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301742
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001743 } else { // MULTICAST FLOW
1744 if (group_id >= 0) {
1745 BCMOLT_MSG_FIELD_SET(&cfg, group_id, group_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001746 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001747 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1748 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001749 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001750
1751 {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001752 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001753 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001754 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
1755 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001756 }
1757
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001758 if (classifier.dst_mac().size() > 0) {
1759 bcmos_mac_address d_mac = {};
1760 bcmos_mac_address_init(&d_mac);
1761 memcpy(d_mac.u8, classifier.dst_mac().data(), sizeof(d_mac.u8));
1762 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_mac %02x:%02x:%02x:%02x:%02x:%02x\n", d_mac.u8[0],
1763 d_mac.u8[1], d_mac.u8[2], d_mac.u8[3], d_mac.u8[4], d_mac.u8[5]);
1764 BCMOLT_FIELD_SET(&c_val, classifier, dst_mac, d_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001765 }
1766
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001767 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001768 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001769 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001770 }
1771 */
1772
1773 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001774 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
1775 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001776 }
1777
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001778 if (classifier.dst_ip()) {
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08001779 bcmos_ipv4_address d_ip = {};
1780 bcmos_ipv4_address_init(&d_ip);
1781 d_ip.u32 = classifier.dst_ip();
1782 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_ip %04x\n", d_ip.u32);
1783 BCMOLT_FIELD_SET(&c_val, classifier, dst_ip, d_ip);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001784 }
1785
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08001786 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001787 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001788 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001789 }
1790 */
1791
1792 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001793 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
1794 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001795 }
1796
1797 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001798 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
1799 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001800 }
1801
1802 if (!classifier.pkt_tag_type().empty()) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001803 if (classifier.o_vid()) {
1804 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
1805 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
1806 }
1807
1808 if (classifier.i_vid()) {
1809 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
1810 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
1811 }
1812
1813 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
1814 if (classifier.pkt_tag_type().compare("untagged") == 0) {
1815 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
1816 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
1817 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
1818 single_tag = true;
1819
1820 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301821 // OpenOlt adapter will send 0xFF in case of no pbit classification
1822 // If it is any other value (0 to 7), it is for outer pbit classification.
1823 // OpenFlow protocol does not provide inner pbit classification (in case of double tagged packets),
1824 // and VOLTHA has not used any workaround to solve this problem (for ex: use metadata field).
1825 // Also there exists no use case for i-pbit classification, so we can safely ignore this for now.
1826 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001827 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301828 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001829 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
1830 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001831
Jason Huang09b73ea2020-01-08 17:52:05 +08001832 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301833 // Same comments as in case of "single_tag" packets.
1834 // 0xFF means no pbit classification, otherwise a valid PCP (0 to 7).
1835 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001836 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301837 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001838 }
1839 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001840 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001841 }
1842
Jason Huang09b73ea2020-01-08 17:52:05 +08001843 const ::openolt::ActionCmd& cmd = action.cmd();
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001844
Jason Huang09b73ea2020-01-08 17:52:05 +08001845 if (cmd.add_outer_tag()) {
1846 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
1847 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001848 }
1849
Jason Huang09b73ea2020-01-08 17:52:05 +08001850 if (cmd.remove_outer_tag()) {
1851 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
1852 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
1853 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301854
Jason Huang09b73ea2020-01-08 17:52:05 +08001855 if (action.o_vid()) {
1856 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
1857 o_vid = action.o_vid();
1858 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
1859 }
1860
1861 if (action.o_pbits()) {
1862 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
1863 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
1864 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301865
Jason Huang09b73ea2020-01-08 17:52:05 +08001866 if (action.i_vid()) {
1867 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
1868 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
1869 }
1870
1871 if (action.i_pbits()) {
1872 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
1873 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
1874 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301875
Jason Huang09b73ea2020-01-08 17:52:05 +08001876 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
1877
Burak Gurdaga0523592021-02-24 15:17:47 +00001878 if ((access_intf_id >= 0) && (onu_id >= ONU_ID_START)) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001879 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
1880 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00001881 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 +00001882
Jason Huang09b73ea2020-01-08 17:52:05 +08001883 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1884 // Queue 0 on DS subscriber scheduler
1885 tm_val.queue_id = 0;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001886
Jason Huang09b73ea2020-01-08 17:52:05 +08001887 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1888 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1889 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001890
Jason Huang09b73ea2020-01-08 17:52:05 +08001891 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1892 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1893 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001894
Jason Huang09b73ea2020-01-08 17:52:05 +08001895 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1896 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
1897 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 +00001898
Jason Huang09b73ea2020-01-08 17:52:05 +08001899 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1900 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1901 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1902 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 +00001903
Jason Huang09b73ea2020-01-08 17:52:05 +08001904 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
1905 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1906 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1907 }
1908 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
1909 // NNI Scheduler ID
1910 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1911 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1912 // Queue 0 on NNI scheduler
1913 tm_val.queue_id = 0;
1914 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1915 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1916 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_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, queue_id = %d, sched_id = %d, intf_type %s\n", \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001919 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1920 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1921
Jason Huang09b73ea2020-01-08 17:52:05 +08001922 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1923 /* Fetch TM QMP ID mapped to US NNI scheduler */
1924 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
1925 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1926 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1927 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1928 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 +00001929
Jason Huang09b73ea2020-01-08 17:52:05 +08001930 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 +00001931 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1932 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001933 }
Shad Ansari39739bc2018-09-13 21:38:37 +00001934 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301935 } else {
1936 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1937 tm_val.queue_id = 0;
1938
1939 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
1940 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1941 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
1942
1943 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1944 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
1945 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00001946 }
1947
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001948 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001949
Girish Gowdra252f4972020-09-07 21:24:01 -07001950#ifndef SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001951 // BAL 3.1 supports statistics only for unicast flows.
1952 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1953 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
1954 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001955#endif // SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001956
Girish Gowdra252f4972020-09-07 21:24:01 -07001957#ifndef SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001958#ifdef FLOW_CHECKER
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001959 //Flow Checker, To avoid duplicate flow.
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001960 if (flow_id_counters != 0) {
1961 bool b_duplicate_flow = false;
Jason Huang09b73ea2020-01-08 17:52:05 +08001962 std::map<flow_pair, int>::iterator it;
1963
1964 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1965 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(it->first.first, it->first.second, ONU_ID)) && \
1966 (key.flow_type == it->first.second) && \
1967 (cfg.data.svc_port_id == get_flow_status(it->first.first, it->first.second, SVC_PORT_ID)) && \
1968 (cfg.data.priority == get_flow_status(it->first.first, it->first.second, PRIORITY)) && \
1969 (cfg.data.cookie == get_flow_status(it->first.first, it->first.second, COOKIE)) && \
1970 (cfg.data.ingress_intf.intf_type == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_TYPE)) && \
1971 (cfg.data.ingress_intf.intf_id == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_ID)) && \
1972 (cfg.data.egress_intf.intf_type == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_TYPE)) && \
1973 (cfg.data.egress_intf.intf_id == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_ID)) && \
1974 (c_val.o_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_VID)) && \
1975 (c_val.o_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_PBITS)) && \
1976 (c_val.i_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_VID)) && \
1977 (c_val.i_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_PBITS)) && \
1978 (c_val.ether_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_ETHER_TYPE)) && \
1979 (c_val.ip_proto == get_flow_status(it->first.first, it->first.second, CLASSIFIER_IP_PROTO)) && \
1980 (c_val.src_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_SRC_PORT)) && \
1981 (c_val.dst_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_DST_PORT)) && \
1982 (c_val.pkt_tag_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_PKT_TAG_TYPE)) && \
1983 (cfg.data.egress_qos.type == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TYPE)) && \
1984 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_QUEUE_ID)) && \
1985 (cfg.data.egress_qos.tm_sched.id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TM_SCHED_ID)) && \
1986 (a_val.cmds_bitmask == get_flow_status(it->first.first, it->first.second, ACTION_CMDS_BITMASK)) && \
1987 (a_val.o_vid == get_flow_status(it->first.first, it->first.second, ACTION_O_VID)) && \
1988 (a_val.i_vid == get_flow_status(it->first.first, it->first.second, ACTION_I_VID)) && \
1989 (a_val.o_pbits == get_flow_status(it->first.first, it->first.second, ACTION_O_PBITS)) && \
1990 (a_val.i_pbits == get_flow_status(it->first.first, it->first.second, ACTION_I_PBITS)) && \
1991 (cfg.data.state == get_flow_status(it->first.first, it->first.second, STATE)) && \
1992 (cfg.data.group_id == get_flow_status(it->first.first, it->first.second, GROUP_ID));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001993#ifdef SHOW_FLOW_PARAM
1994 // Flow Parameter
1995 FLOW_PARAM_LOG();
1996#endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001997 if (b_duplicate_flow) {
1998 FLOW_LOG(WARNING, "Flow duplicate", 0);
1999 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
2000 }
2001 }
2002 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002003#endif // FLOW_CHECKER
2004#endif // SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002005
2006 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2007 if (err) {
2008 FLOW_LOG(ERROR, "Flow add failed", err);
2009 return bcm_to_grpc_err(err, "flow add failed");
2010 } else {
2011 FLOW_LOG(INFO, "Flow add ok", err);
2012 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002013 flow_map[std::pair<int, int>(key.flow_id,key.flow_type)] = flow_map.size();
2014 flow_id_counters = flow_map.size();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002015 bcmos_fastlock_unlock(&data_lock, 0);
Girish Gowdra252f4972020-09-07 21:24:01 -07002016
2017 }
Burak Gurdaga0523592021-02-24 15:17:47 +00002018
2019 /*
2020 Enable AES encryption on GEM ports if they are used in downstream unicast flows.
2021 Rationale: We can't do upstream encryption in GPON. This change addresses the common denominator (and also minimum viable)
2022 use case for both technologies which is downstream unicast GEM port encryption. Since the downstream traffic is inherently
2023 broadcast to all the ONUs behind a PON port, encrypting the individual subscriber traffic in this direction is important
2024 and considered good enough in terms of security (See Section 12.1 of G.984.3). For upstream unicast and downstream multicast
2025 GEM encryption, we need to make additional changes specific to XGSPON. This will be done as a future work.
2026 */
2027 if (aes_enabled && (access_intf_id >= 0) && (gemport_id >= GEM_PORT_ID_START) && (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM)) {
2028 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);
2029 enable_encryption_for_gem_port(access_intf_id, gemport_id);
2030 } else {
2031 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);
2032 }
2033
Girish Gowdra252f4972020-09-07 21:24:01 -07002034 return Status::OK;
2035}
2036
2037Status FlowRemoveWrapper_(const ::openolt::Flow* request) {
2038 const std::string flow_type = request->flow_type();
2039 uint64_t voltha_flow_id = request->flow_id();
2040 Status st;
2041
2042 // If Voltha flow is not installed, return fail
2043 if (! is_voltha_flow_installed(voltha_flow_id)) {
2044 OPENOLT_LOG(ERROR, openolt_log_id, "voltha_flow_id=%lu not found\n", voltha_flow_id);
2045 return ::Status(grpc::StatusCode::NOT_FOUND, "voltha-flow-not-found");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002046 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04002047
Girish Gowdra252f4972020-09-07 21:24:01 -07002048 const device_flow *dev_fl = get_device_flow(voltha_flow_id);
2049 if (dev_fl == NULL) {
2050 OPENOLT_LOG(ERROR, openolt_log_id, "device flow for voltha_flow_id=%lu in the cache is NULL\n", voltha_flow_id);
2051 return ::Status(grpc::StatusCode::INTERNAL, "device-flow-null-in-cache");
2052 }
2053 if (dev_fl->is_flow_replicated) {
2054 // Note: Here we are ignoring FlowRemove failures
2055 for (int i=0; i<NUMBER_OF_REPLICATED_FLOWS; i++) {
2056 st = FlowRemove_(dev_fl->params[i].flow_id, flow_type);
2057 if (st.error_code() == grpc::StatusCode::OK) {
2058 free_flow_id(dev_fl->params[i].flow_id);
2059 }
2060 }
2061 } else {
2062 // Note: Here we are ignoring FlowRemove failures
2063 st = FlowRemove_(dev_fl->params[0].flow_id, flow_type);
2064 if (st.error_code() == grpc::StatusCode::OK) {
2065 free_flow_id(dev_fl->params[0].flow_id);
2066 }
2067 }
2068 // remove the flow from cache on voltha flow removal
2069 remove_voltha_flow_from_cache(voltha_flow_id);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002070 return Status::OK;
2071}
2072
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002073Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
2074
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002075 bcmolt_flow_cfg cfg;
2076 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002077
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002078 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002079 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002080 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002081 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002082 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002083 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002084 } else if(flow_type.compare(multicast) == 0) {
2085 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002086 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002087 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002088 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
2089 }
2090
Jason Huang09b73ea2020-01-08 17:52:05 +08002091 OPENOLT_LOG(INFO, openolt_log_id, "flow remove received for flow_id=%u, flow_type=%s\n",
2092 flow_id, flow_type.c_str());
2093
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002094 bcmos_fastlock_lock(&acl_packet_trap_handler_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002095 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
2096 int32_t gemport_id = -1;
2097 int32_t intf_id = -1;
2098 int16_t acl_id = -1;
2099 if (flow_to_acl_map.count(fl_id_fl_dir) > 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002100
2101 acl_id_intf_id ac_id_if_id = flow_to_acl_map[fl_id_fl_dir];
2102 acl_id = std::get<0>(ac_id_if_id);
2103 intf_id = std::get<1>(ac_id_if_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002104 // cleanup acl only if it is a valid acl. If not valid acl, it may be datapath flow.
2105 if (acl_id >= 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002106 Status resp = handle_acl_rule_cleanup(acl_id, intf_id, flow_type);
Jason Huang09b73ea2020-01-08 17:52:05 +08002107 if (resp.ok()) {
2108 OPENOLT_LOG(INFO, openolt_log_id, "acl removed ok for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2109 flow_to_acl_map.erase(fl_id_fl_dir);
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002110
2111 // 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
2112 if (trap_to_host_pkt_info_with_vlan_for_flow_id.count(flow_id) > 0) {
2113 trap_to_host_pkt_info_with_vlan pkt_info_with_vlan = trap_to_host_pkt_info_with_vlan_for_flow_id[flow_id];
2114 // Formulate the trap_to_host_pkt_info tuple key
2115 trap_to_host_pkt_info pkt_info(std::get<0>(pkt_info_with_vlan),
2116 std::get<1>(pkt_info_with_vlan),
2117 std::get<2>(pkt_info_with_vlan),
2118 std::get<3>(pkt_info_with_vlan));
2119 // Extract the value corresponding to trap_to_host_pkt_info key from trap_to_host_vlan_ids_for_trap_to_host_pkt_info
2120 // The value is a list of vlan_ids for the given trap_to_host_pkt_info key
2121 // Remove the vlan_id from the list that corresponded to the flow being removed.
2122 if (trap_to_host_vlan_ids_for_trap_to_host_pkt_info.count(pkt_info) > 0) {
2123 trap_to_host_vlan_ids_for_trap_to_host_pkt_info[pkt_info].remove(std::get<4>(pkt_info_with_vlan));
2124 } else {
2125 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",
2126 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));
2127 }
2128
2129 } else {
2130 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);
2131 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002132 } else {
2133 OPENOLT_LOG(ERROR, openolt_log_id, "acl remove error for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2134 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002135 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002136 return resp;
2137 }
2138 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002139 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002140
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002141 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002142 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002143 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002144 flowid_to_gemport.erase(key.flow_id);
2145 port_to_flows[port_no].erase(key.flow_id);
2146 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
2147 }
2148 else
2149 {
2150 flowid_to_port.erase(key.flow_id);
2151 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002152 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002153
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002154 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002155
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002156 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002157 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002158 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 -04002159 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
2160 }
2161
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002162 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002163 if (flow_id_counters != 0) {
2164 std::map<flow_pair, int>::iterator it;
2165 for(it = flow_map.begin(); it != flow_map.end(); it++) {
2166 if (it->first.first == flow_id && it->first.second == key.flow_type) {
2167 flow_id_counters -= 1;
2168 flow_map.erase(it);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002169 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002170 }
2171 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002172 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
2173
Jason Huang09b73ea2020-01-08 17:52:05 +08002174 flow_to_acl_map.erase(fl_id_fl_dir);
2175
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002176 bcmos_fastlock_unlock(&data_lock, 0);
2177
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002178 return Status::OK;
2179}
2180
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002181bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
2182 bcmos_errno err;
2183 bcmolt_tm_sched_cfg tm_sched_cfg;
2184 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2185 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
2186
Jason Huangbf45ffb2019-10-30 17:29:02 +08002187 //check TM scheduler has configured or not
2188 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2189 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002190 #ifdef TEST_MODE
2191 // It is impossible to mock the setting of tm_sched_cfg.data.state because
2192 // the actual bcmolt_cfg_get passes the address of tm_sched_cfg.hdr and we cannot
2193 // set the tm_sched_cfg.data.state. So a new stub function is created and address
2194 // of tm_sched_cfg is passed. This is one-of case where we need to add test specific
2195 // code in production code.
2196 err = bcmolt_cfg_get__tm_sched_stub(dev_id, &tm_sched_cfg);
2197 #else
Jason Huangbf45ffb2019-10-30 17:29:02 +08002198 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002199 #endif
Jason Huangbf45ffb2019-10-30 17:29:02 +08002200 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002201 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 +08002202 return err;
2203 }
2204 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
2205 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
2206 return BCM_ERR_OK;
2207 }
2208
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002209 // bcmbal_tm_sched_owner
2210 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2211
2212 /**< The output of the tm_sched object instance */
2213 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
2214
2215 if (direction.compare(upstream) == 0) {
2216 // In upstream it is NNI scheduler
2217 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
2218 } else if (direction.compare(downstream) == 0) {
2219 // In downstream it is PON scheduler
2220 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2221 }
2222
2223 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2224
2225 // bcmbal_tm_sched_type
2226 // set the deafult policy to strict priority
2227 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2228
2229 // num_priorities: Max number of strict priority scheduling elements
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002230 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, NUM_OF_PRIORITIES);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002231
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002232 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2233 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002234 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
2235 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002236 return err;
2237 }
2238
2239 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2240 direction.c_str(), tm_sched_key.id, intf_id);
2241 return BCM_ERR_OK;
2242}
2243
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002244bcmos_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 -07002245 uint32_t alloc_id, ::tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
2246 ::tech_profile::SchedulingPolicy sched_policy, ::tech_profile::TrafficShapingInfo tf_sh_info,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002247 uint32_t tech_profile_id) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002248
2249 bcmos_errno err;
2250
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002251 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002252 bcmolt_tm_sched_cfg tm_sched_cfg;
2253 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002254 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 -04002255
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002256 // bcmbal_tm_sched_owner
2257 // In downstream it is sub_term scheduler
2258 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002259
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002260 /**< The output of the tm_sched object instance */
2261 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002262
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002263 // bcmbal_tm_sched_parent
2264 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2265 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
2266 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 +00002267 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002268 be achieved using the' virtual' type of attachment.
2269 tm_sched_owner.u.sub_term.intf_id = intf_id;
2270 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2271 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002272
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002273 // bcmbal_tm_sched_type
2274 // set the deafult policy to strict priority
2275 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002276
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002277 // num_priorities: Max number of strict priority scheduling elements
2278 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002279
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002280 // bcmbal_tm_shaping
2281 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2282 uint32_t cir = tf_sh_info.cir();
2283 uint32_t pir = tf_sh_info.pir();
2284 uint32_t burst = tf_sh_info.pbs();
2285 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2286 cir, pir, burst);
2287 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2288 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2289 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2290 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2291 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2292 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002293 }
2294
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002295 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002296 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002297 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002298intf_id %d, onu_id %d, uni_id %d, port_no %u, err = %s\n", tm_sched_key.id, intf_id, onu_id, uni_id, \
2299port_no, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002300 return err;
2301 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002302 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2303uni_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 -08002304
2305 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002306 bcmolt_itupon_alloc_cfg cfg;
2307 bcmolt_itupon_alloc_key key = { };
2308 key.pon_ni = intf_id;
2309 key.alloc_id = alloc_id;
2310 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
Burak Gurdag623fada2021-04-20 22:02:36 +00002311 /*
2312 PIR: Maximum Bandwidth
2313 CIR: Assured Bandwidth
2314 GIR: Fixed Bandwidth
2315 */
Burak Gurdag03919c72020-02-04 22:46:57 +00002316 int pir_bw = tf_sh_info.pir()*125; // conversion from kbps to bytes/sec
2317 int cir_bw = tf_sh_info.cir()*125; // conversion from kbps to bytes/sec
Burak Gurdag623fada2021-04-20 22:02:36 +00002318 int gir_bw = tf_sh_info.gir()*125; // conversion from kbps to bytes/sec
2319 int guaranteed_bw = cir_bw+gir_bw;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002320 //offset to match bandwidth granularity
2321 int offset_pir_bw = pir_bw%bw_granularity;
Burak Gurdag623fada2021-04-20 22:02:36 +00002322 int offset_gir_bw = gir_bw%bw_granularity;
2323 int offset_guaranteed_bw = guaranteed_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002324
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002325 pir_bw = pir_bw - offset_pir_bw;
Burak Gurdag623fada2021-04-20 22:02:36 +00002326 gir_bw = gir_bw - offset_gir_bw;
2327 guaranteed_bw = guaranteed_bw - offset_guaranteed_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002328
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002329 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002330
Burak Gurdag623fada2021-04-20 22:02:36 +00002331 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);
2332
2333 if (pir_bw == 0) {
2334 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be at least %d bytes/sec\n",
2335 (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2336 return BCM_ERR_PARM;
2337 } else if (pir_bw < guaranteed_bw) {
2338 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed bandwidth (%d)\n",
2339 pir_bw, guaranteed_bw);
2340 return BCM_ERR_PARM;
2341 }
2342
2343 // Setting additional bw eligibility and validating bw provisionings
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002344 switch (additional_bw) {
Burak Gurdag623fada2021-04-20 22:02:36 +00002345
2346 case tech_profile::AdditionalBW::AdditionalBW_BestEffort: //AdditionalBW_BestEffort - For T-Cont types 4 & 5
2347 if (pir_bw == guaranteed_bw) {
2348 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2349bandwidth for additional bandwidth eligibility of type Best Effort\n");
2350 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002351 }
2352 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2353 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002354
2355 case tech_profile::AdditionalBW::AdditionalBW_NA: //AdditionalBW_NA - For T-Cont types 3 & 5
2356 if (guaranteed_bw == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002357 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2358additional bandwidth eligibility of type Non-Assured (NA)\n");
2359 return BCM_ERR_PARM;
Burak Gurdag623fada2021-04-20 22:02:36 +00002360 } else if (pir_bw == guaranteed_bw) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002361 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
Burak Gurdag623fada2021-04-20 22:02:36 +00002362bandwidth for additional bandwidth eligibility of type Non-Assured\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002363 return BCM_ERR_PARM;
2364 }
2365 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2366 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002367
2368 case tech_profile::AdditionalBW::AdditionalBW_None: //AdditionalBW_None - For T-Cont types 1 & 2
2369 if (guaranteed_bw != pir_bw) {
2370 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be equal to maximum bandwidth \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002371for additional bandwidth eligibility of type None\n");
2372 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002373 }
2374 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2375 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002376
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002377 default:
Burak Gurdag623fada2021-04-20 22:02:36 +00002378 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid additional bandwidth eligibility value (%d) supplied.\n", additional_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002379 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002380 }
Burak Gurdag623fada2021-04-20 22:02:36 +00002381
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002382 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2383 in a fine granularity. */
2384 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
Burak Gurdag623fada2021-04-20 22:02:36 +00002385 /* Since we can assign minimum 64000 bytes/sec for cbr_rt_bw, we prefer assigning
2386 gir_bw to cbr_nrt_bw to allow smaller amounts.
2387 TODO: Specify CBR_RT_BW and CBR_NRT_BW separately from VOLTHA */
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002388 /* Fixed Bandwidth with no critical requirement of shaping */
Burak Gurdag623fada2021-04-20 22:02:36 +00002389 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, gir_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002390 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
Burak Gurdag623fada2021-04-20 22:02:36 +00002391 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, guaranteed_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002392 /* Maximum allocated bandwidth allowed for this alloc ID */
2393 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
Burak Gurdag623fada2021-04-20 22:02:36 +00002394
2395 if (pir_bw == gir_bw) { // T-Cont Type 1 --> set alloc type to NONE
2396 // the condition cir_bw == 0 is implicitly satistied
2397 OPENOLT_LOG(INFO, openolt_log_id, "Setting alloc type to NONE since maximum bandwidth is equal to fixed bandwidth\n");
2398 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NONE);
2399 } else { // For other T-Cont types, set alloc type to NSR. TODO: read the default from a config file.
2400 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
2401 }
2402
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002403 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002404 for skipped allocations during quiet window */
2405 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2406 /**< Allocation Profile index for CBR non-RT Bandwidth */
2407 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2408 /**< Allocation Profile index for CBR RT Bandwidth */
2409 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2410 /**< Alloc ID Weight used in case of Extended DBA mode */
2411 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2412 /**< Alloc ID Priority used in case of Extended DBA mode */
2413 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2414 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002415
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002416 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002417 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002418 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 +00002419port_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 -08002420 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002421 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002422#ifndef SCALE_AND_PERF
Girish Gowdra96461052019-11-22 20:13:59 +05302423 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
2424 if (err) {
2425 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2426port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
2427 return err;
2428 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002429#endif
Girish Gowdra96461052019-11-22 20:13:59 +05302430
2431 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
2432port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
2433
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002434 }
2435
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002436 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002437}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002438
Girish Gowdra252f4972020-09-07 21:24:01 -07002439Status CreateTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002440 uint32_t intf_id = traffic_scheds->intf_id();
2441 uint32_t onu_id = traffic_scheds->onu_id();
2442 uint32_t uni_id = traffic_scheds->uni_id();
2443 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002444 std::string direction;
2445 unsigned int alloc_id;
Girish Gowdra252f4972020-09-07 21:24:01 -07002446 ::tech_profile::SchedulerConfig sched_config;
2447 ::tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002448 uint32_t priority;
2449 uint32_t weight;
Girish Gowdra252f4972020-09-07 21:24:01 -07002450 ::tech_profile::SchedulingPolicy sched_policy;
2451 ::tech_profile::TrafficShapingInfo traffic_shaping_info;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002452 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002453 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002454
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002455 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002456 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002457
2458 direction = GetDirection(traffic_sched.direction());
2459 if (direction.compare("direction-not-supported") == 0)
2460 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2461
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002462 alloc_id = traffic_sched.alloc_id();
2463 sched_config = traffic_sched.scheduler();
2464 additional_bw = sched_config.additional_bw();
2465 priority = sched_config.priority();
2466 weight = sched_config.weight();
2467 sched_policy = sched_config.sched_policy();
2468 traffic_shaping_info = traffic_sched.traffic_shaping_info();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002469 tech_profile_id = traffic_sched.tech_profile_id();
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002470 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002471 sched_policy, traffic_shaping_info, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002472 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002473 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002474 return bcm_to_grpc_err(err, "Failed to create scheduler");
2475 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002476 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002477 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002478}
Jonathan Davis70c21812018-07-19 15:32:10 -04002479
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002480bcmos_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 -04002481
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002482 bcmos_errno err;
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302483 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302484 bcmolt_status los_status;
Girish Gowdra96461052019-11-22 20:13:59 +05302485 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002486
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002487 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002488 bcmolt_itupon_alloc_cfg cfg;
2489 bcmolt_itupon_alloc_key key = { };
2490 key.pon_ni = intf_id;
2491 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302492 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002493
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002494 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002495 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2496 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002497 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2498 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002499 return err;
2500 }
Girish Gowdra96461052019-11-22 20:13:59 +05302501
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302502 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302503 if (err == BCM_ERR_OK) {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302504 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_OFF) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002505#ifndef SCALE_AND_PERF
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302506 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 +05302507 intf_id);
2508 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2509 if (err) {
2510 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2511 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
2512 return err;
2513 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002514#endif
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302515 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302516 else if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_ON) {
2517 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is enabled but LoS status is ON, not waiting for alloc cfg clear response\n",
2518 intf_id);
2519 }
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302520 else if (state == BCMOLT_INTERFACE_STATE_INACTIVE) {
2521 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is disabled, not waiting for alloc cfg clear response\n",
2522 intf_id);
2523 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302524 } else {
2525 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 +05302526 intf_id, bcmos_strerror(err));
Girish Gowdra96461052019-11-22 20:13:59 +05302527 return err;
2528 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002529 } else if (direction == downstream) {
2530 bcmolt_tm_sched_cfg cfg;
2531 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002532
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002533 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2534 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302535 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002536 } else {
2537 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2538 return BCM_ERR_OK;
2539 }
Girish Gowdra96461052019-11-22 20:13:59 +05302540
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002541 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2542 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2543 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002544 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002545intf_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 +00002546 return err;
2547 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002548 }
2549
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002550 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d, tech_profile_id %d\n",
2551 direction.c_str(), sched_id, intf_id, onu_id, tech_profile_id);
2552 free_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002553 return BCM_ERR_OK;
2554}
2555
Girish Gowdra252f4972020-09-07 21:24:01 -07002556Status RemoveTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002557 uint32_t intf_id = traffic_scheds->intf_id();
2558 uint32_t onu_id = traffic_scheds->onu_id();
2559 uint32_t uni_id = traffic_scheds->uni_id();
2560 std::string direction;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002561 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002562 bcmos_errno err;
2563
2564 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002565 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002566
2567 direction = GetDirection(traffic_sched.direction());
2568 if (direction.compare("direction-not-supported") == 0)
2569 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2570
2571 int alloc_id = traffic_sched.alloc_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002572 int tech_profile_id = traffic_sched.tech_profile_id();
2573 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002574 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002575 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002576 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2577 }
2578 }
2579 return Status::OK;
2580}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002581
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002582bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2583 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002584 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002585 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2586 bcmolt_tm_qmp_key tm_qmp_key;
2587 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002588
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002589 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2590 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002591 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed tm queue mapping profile count is 16.\n");
2592 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002593 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002594
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002595 tm_qmp_key.id = tm_qmp_id;
2596 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2597 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2598 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002599
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002600 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2601 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2602 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002603 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2604 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002605
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002606 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002607 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002608 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2609 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002610 return err;
2611 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002612
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002613 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2614 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002615 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002616}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002617
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002618bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2619 bcmos_errno err;
2620 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2621 bcmolt_tm_qmp_key tm_qmp_key;
2622 tm_qmp_key.id = tm_qmp_id;
2623
2624 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2625 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2626 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002627 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2628 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002629 return err;
2630 }
2631
2632 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2633 tm_qmp_key.id);
2634 return BCM_ERR_OK;
2635}
2636
2637bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2638 bcmos_errno err;
2639
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002640 /* Create default queues on the given PON/NNI scheduler */
2641 for (int queue_id = 0; queue_id < NUMBER_OF_DEFAULT_INTERFACE_QUEUES; queue_id++) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002642 bcmolt_tm_queue_cfg tm_queue_cfg;
2643 bcmolt_tm_queue_key tm_queue_key = {};
2644 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2645 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002646 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2647 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2648 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002649
2650 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2651 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2652 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2653
2654 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2655 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002656 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", \
2657 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 +00002658 return err;
2659 }
2660
2661 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2662 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2663 }
2664 return BCM_ERR_OK;
2665}
2666
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002667bcmos_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 +00002668 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 +00002669 bcmos_errno err;
2670 bcmolt_tm_queue_cfg cfg;
2671 bcmolt_tm_queue_key key = { };
2672 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 +00002673gemport_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 +00002674
2675 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002676 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002677
2678 if (priority > 7) {
2679 return BCM_ERR_RANGE;
2680 }
2681
2682 /* FIXME: The upstream queues have to be created once only.
2683 The upstream queues on the NNI scheduler are shared by all subscribers.
2684 When the first scheduler comes in, the queues get created, and are re-used by all others.
2685 Also, these queues should be present until the last subscriber exits the system.
2686 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2687
2688 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2689 for each GEM in TECH PROFILE */
2690 key.id = queue_id_list[priority];
2691
2692 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2693 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2694 key.id = 0;
2695 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2696 }
2697 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2698 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2699 }
2700 else {
2701 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2702 }
2703
2704 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2705
2706 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2707 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
2708
2709 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2710 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002711 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002712sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, tech_profile_id %d, err = %s\n", \
2713 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 +00002714 return err;
2715 }
2716
Girish Gowdra252f4972020-09-07 21:24:01 -07002717 if (direction.compare(upstream) == 0) {
2718 Status st = install_gem_port(access_intf_id, onu_id, gemport_id);
2719 if (st.error_code() != grpc::StatusCode::ALREADY_EXISTS && st.error_code() != grpc::StatusCode::OK) {
2720 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);
2721 return BCM_ERR_INTERNAL;
2722 }
2723 }
2724
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002725 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 +00002726intf_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 +00002727 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002728}
2729
Girish Gowdra252f4972020-09-07 21:24:01 -07002730Status CreateTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002731 uint32_t intf_id = traffic_queues->intf_id();
2732 uint32_t onu_id = traffic_queues->onu_id();
2733 uint32_t uni_id = traffic_queues->uni_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002734 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002735 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002736 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002737 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002738 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 +00002739
2740 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2741 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2742 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2743 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002744 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002745
2746 direction = GetDirection(traffic_queue.direction());
2747 if (direction.compare("direction-not-supported") == 0)
2748 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2749
2750 queues_priority_q[i] = traffic_queue.priority();
2751 queues_pbit_map[i] = traffic_queue.pbit_map();
2752 }
2753
2754 std::vector<uint32_t> tmq_map_profile(8, 0);
2755 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2756 queues_priority_q, COUNT_OF(queues_priority_q));
2757 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002758 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002759
2760 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2761 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002762 err = CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2763 if (err != BCM_ERR_OK) {
2764 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2765 return bcm_to_grpc_err(err, "Failed to create tm queue mapping profile");
2766 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002767 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2768 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2769 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2770 }
2771 }
2772
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002773 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002774 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002775
2776 direction = GetDirection(traffic_queue.direction());
2777 if (direction.compare("direction-not-supported") == 0)
2778 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2779
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002780 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 +00002781
Girish Gowdruf26cf882019-05-01 23:47:58 -07002782 // If the queue exists already, lets not return failure and break the loop.
2783 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002784 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002785 return bcm_to_grpc_err(err, "Failed to create queue");
2786 }
2787 }
2788 return Status::OK;
2789}
2790
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002791bcmos_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 +00002792 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 +00002793 bcmolt_tm_queue_cfg cfg;
2794 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002795 bcmos_errno err;
2796
2797 if (direction == downstream) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002798 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2799 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 +00002800 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002801 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002802 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 -08002803 return BCM_ERR_OK;
2804 }
2805 } else {
Girish Gowdra4fd30672020-11-09 17:23:06 -08002806 // Gemports are bi-directional (except in multicast case). We create the gem port when we create the
2807 // upstream queue (see CreateQueue function) and it makes sense to delete them when remove the upstream queues.
2808 // For multicast case we do not manage the install/remove of gem port in agent application. It is managed by BAL.
2809 // Moreover it also makes sense to remove when upstream queue is getting removed because the upstream queue MUST exist always.
2810 // It is possible that the downstream queues are not created for a subscriber (for ex: upstream EAPoL trap flow only exists
2811 // but no other flow, and in this case only upstream scheduler and queues exist. We do not have a scenario where only downstream
2812 // subscriber flows exist but no upstream )
2813 remove_gem_port(access_intf_id, gemport_id);
2814
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002815 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2816 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002817 return BCM_ERR_OK;
2818 }
2819
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002820 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2821 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2822 // Reset the queue id to 0 when using fixed queue.
2823 key.id = 0;
2824 }
2825 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2826 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2827 }
2828 else {
2829 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2830 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002831
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002832 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2833 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002834 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002835 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, queue_id %d, sched_id %d, \
2836tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n",
2837 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 -08002838 return err;
2839 }
2840
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002841 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2842intf_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 -08002843
2844 return BCM_ERR_OK;
2845}
2846
Girish Gowdra252f4972020-09-07 21:24:01 -07002847Status RemoveTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002848 uint32_t intf_id = traffic_queues->intf_id();
2849 uint32_t onu_id = traffic_queues->onu_id();
2850 uint32_t uni_id = traffic_queues->uni_id();
2851 uint32_t port_no = traffic_queues->port_no();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002852 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002853 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002854 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002855 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002856 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 +00002857
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002858 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002859 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002860
2861 direction = GetDirection(traffic_queue.direction());
2862 if (direction.compare("direction-not-supported") == 0)
2863 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2864
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002865 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 -08002866 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002867 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002868 return bcm_to_grpc_err(err, "Failed to remove queue");
2869 }
Jonathan Davis70c21812018-07-19 15:32:10 -04002870 }
2871
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002872 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 +00002873 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002874 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002875
2876 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
2877 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002878 err = RemoveTrafficQueueMappingProfile(tm_qmp_id);
2879 if (err != BCM_ERR_OK) {
2880 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2881 return bcm_to_grpc_err(err, "Failed to remove tm queue mapping profile");
2882 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002883 }
2884 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002885 clear_qos_type(intf_id, onu_id, uni_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04002886 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04002887}
Jason Huangbf45ffb2019-10-30 17:29:02 +08002888
Girish Gowdra252f4972020-09-07 21:24:01 -07002889Status PerformGroupOperation_(const ::openolt::Group *group_cfg) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002890
2891 bcmos_errno err;
2892 bcmolt_group_key key = {};
2893 bcmolt_group_cfg grp_cfg_obj;
2894 bcmolt_group_members_update grp_mem_upd;
2895 bcmolt_members_update_command grp_mem_upd_cmd;
2896 bcmolt_group_member_info member_info = {};
2897 bcmolt_group_member_info_list_u8 members = {};
2898 bcmolt_intf_ref interface_ref = {};
2899 bcmolt_egress_qos egress_qos = {};
2900 bcmolt_tm_sched_ref tm_sched_ref = {};
2901 bcmolt_action a_val = {};
2902
2903 uint32_t group_id = group_cfg->group_id();
2904
2905 OPENOLT_LOG(INFO, openolt_log_id, "PerformGroupOperation request received for Group %d\n", group_id);
2906
2907 if (group_id >= 0) {
2908 key.id = group_id;
2909 }
2910 else {
2911 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
2912 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
2913 }
2914
2915 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2916 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
2917
2918 OPENOLT_LOG(INFO, openolt_log_id, "Checking if Group %d exists...\n",group_id);
2919
2920 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
2921 if (err != BCM_ERR_OK) {
2922 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
2923 return bcm_to_grpc_err(err, "Error in querying group");
2924 }
2925
2926 members.len = group_cfg->members_size();
2927
2928 // IMPORTANT: A member cannot be added to a group if the group type is not determined.
2929 // Group type is determined after a flow is assigned to it.
2930 // Therefore, a group must be created first, then a flow (with multicast type) must be assigned to it.
2931 // Only then we can add members to the group.
2932
2933 // if group does not exist, create it and return.
2934 if (grp_cfg_obj.data.state == BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
2935
2936 if (members.len != 0) {
2937 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);
2938 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Non-empty member list given for non-existent group");
2939 } else {
2940
2941 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2942 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, cookie, key.id);
2943
2944 /* Setting group actions and action parameters, if any.
2945 Only remove_outer_tag and translate_inner_tag actions and i_vid action parameter
2946 are supported for multicast groups in BAL 3.1.
2947 */
2948 const ::openolt::Action& action = group_cfg->action();
2949 const ::openolt::ActionCmd &cmd = action.cmd();
2950
2951 bcmolt_action_cmd_id cmd_bmask = BCMOLT_ACTION_CMD_ID_NONE;
2952 if (cmd.remove_outer_tag()) {
2953 OPENOLT_LOG(INFO, openolt_log_id, "Action remove_outer_tag applied to Group %d.\n", group_id);
2954 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
2955 }
2956
2957 if (cmd.translate_inner_tag()) {
2958 OPENOLT_LOG(INFO, openolt_log_id, "Action translate_inner_tag applied to Group %d.\n", group_id);
2959 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG);
2960 }
2961
2962 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, cmd_bmask);
2963
2964 if (action.i_vid()) {
2965 OPENOLT_LOG(INFO, openolt_log_id, "Setting action parameter i_vid=%d for Group %d.\n", action.i_vid(), group_id);
2966 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
2967 }
2968
2969 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, action, a_val);
2970
2971 // Create group
2972 err = bcmolt_cfg_set(dev_id, &(grp_cfg_obj.hdr));
2973
2974 if (BCM_ERR_OK != err) {
2975 BCM_LOG(ERROR, openolt_log_id, "Failed to create Group %d, err = %s (%d)\n", key.id, bcmos_strerror(err), err);
2976 return bcm_to_grpc_err(err, "Error in creating group");
2977 }
2978
2979 BCM_LOG(INFO, openolt_log_id, "Group %d has been created and configured with empty member list.\n", key.id);
2980 return Status::OK;
2981 }
2982 }
2983
2984 // The group already exists. Continue configuring it according to the update member command.
2985
2986 OPENOLT_LOG(INFO, openolt_log_id, "Configuring existing Group %d.\n",group_id);
2987
2988 // MEMBER LIST CONSTRUCTION
2989 // Note that members.len can be 0 here. if the group already exists and the command is SET then sending
2990 // empty list to the group is a legit operation and this actually empties the member list.
2991 members.arr = (bcmolt_group_member_info*)bcmos_calloc((members.len)*sizeof(bcmolt_group_member_info));
2992
2993 if (!members.arr) {
2994 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to allocate memory for group member list.\n");
2995 return grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "Memory exhausted during member list creation");
2996 }
2997
2998 /* SET GROUP MEMBERS UPDATE COMMAND */
Girish Gowdra252f4972020-09-07 21:24:01 -07002999 ::openolt::Group::GroupMembersCommand command = group_cfg->command();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003000 switch(command) {
Girish Gowdra252f4972020-09-07 21:24:01 -07003001 case ::openolt::Group::SET_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003002 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_SET;
3003 OPENOLT_LOG(INFO, openolt_log_id, "Setting %d members for Group %d.\n", members.len, group_id);
3004 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003005 case ::openolt::Group::ADD_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003006 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_ADD;
3007 OPENOLT_LOG(INFO, openolt_log_id, "Adding %d members to Group %d.\n", members.len, group_id);
3008 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003009 case ::openolt::Group::REMOVE_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003010 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_REMOVE;
3011 OPENOLT_LOG(INFO, openolt_log_id, "Removing %d members from Group %d.\n", members.len, group_id);
3012 break;
3013 default :
3014 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid value %d for group member command.\n", command);
3015 bcmos_free(members.arr);
3016 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group member command");
3017 }
3018
3019 // SET MEMBERS LIST
3020 for (int i = 0; i < members.len; i++) {
3021
Girish Gowdra252f4972020-09-07 21:24:01 -07003022 if (command == ::openolt::Group::REMOVE_MEMBERS) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003023 OPENOLT_LOG(INFO, openolt_log_id, "Removing group member %d from group %d\n",i,key.id);
3024 } else {
3025 OPENOLT_LOG(INFO, openolt_log_id, "Adding group member %d to group %d\n",i,key.id);
3026 }
3027
Girish Gowdra252f4972020-09-07 21:24:01 -07003028 ::openolt::GroupMember *member = (::openolt::GroupMember *) &group_cfg->members()[i];
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003029
3030 // Set member interface type
Girish Gowdra252f4972020-09-07 21:24:01 -07003031 ::openolt::GroupMember::InterfaceType if_type = member->interface_type();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003032 switch(if_type){
Girish Gowdra252f4972020-09-07 21:24:01 -07003033 case ::openolt::GroupMember::PON :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003034 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_PON);
3035 OPENOLT_LOG(INFO, openolt_log_id, "Interface type PON is assigned to GroupMember %d\n",i);
3036 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003037 case ::openolt::GroupMember::EPON_1G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003038 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_1_G);
3039 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_1G is assigned to GroupMember %d\n",i);
3040 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003041 case ::openolt::GroupMember::EPON_10G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003042 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_10_G);
3043 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_10G is assigned to GroupMember %d\n",i);
3044 break;
3045 default :
3046 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid interface type value %d for GroupMember %d.\n",if_type,i);
3047 bcmos_free(members.arr);
3048 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface type for a group member");
3049 }
3050
3051 // Set member interface id
3052 if (member->interface_id() >= 0) {
3053 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_id, member->interface_id());
3054 OPENOLT_LOG(INFO, openolt_log_id, "Interface %d is assigned to GroupMember %d\n", member->interface_id(), i);
3055 } else {
3056 bcmos_free(members.arr);
3057 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface id for a group member");
3058 }
3059
3060 // Set member interface_ref
3061 BCMOLT_FIELD_SET(&member_info, group_member_info, intf, interface_ref);
3062
3063 // Set member gem_port_id. This must be a multicast gemport.
3064 if (member->gem_port_id() >= 0) {
3065 BCMOLT_FIELD_SET(&member_info, group_member_info, svc_port_id, member->gem_port_id());
3066 OPENOLT_LOG(INFO, openolt_log_id, "GEM Port %d is assigned to GroupMember %d\n", member->gem_port_id(), i);
3067 } else {
3068 bcmos_free(members.arr);
3069 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid gem port id for a group member");
3070 }
3071
3072 // Set member scheduler id and queue_id
3073 uint32_t tm_sched_id = get_default_tm_sched_id(member->interface_id(), downstream);
3074 OPENOLT_LOG(INFO, openolt_log_id, "Scheduler %d is assigned to GroupMember %d\n", tm_sched_id, i);
3075 BCMOLT_FIELD_SET(&tm_sched_ref, tm_sched_ref, id, tm_sched_id);
3076 BCMOLT_FIELD_SET(&egress_qos, egress_qos, tm_sched, tm_sched_ref);
3077
3078 // We assume that all multicast traffic destined to a PON port is using the same fixed queue.
3079 uint32_t tm_queue_id;
3080 if (member->priority() >= 0 && member->priority() < NUMBER_OF_DEFAULT_INTERFACE_QUEUES) {
3081 tm_queue_id = queue_id_list[member->priority()];
3082 OPENOLT_LOG(INFO, openolt_log_id, "Queue %d is assigned to GroupMember %d\n", tm_queue_id, i);
3083 BCMOLT_FIELD_SET(&egress_qos, egress_qos, type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
3084 BCMOLT_FIELD_SET(&egress_qos.u.fixed_queue, egress_qos_fixed_queue, queue_id, tm_queue_id);
3085 } else {
3086 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid fixed queue priority/ID %d for GroupMember %d\n", member->priority(), i);
3087 bcmos_free(members.arr);
3088 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid queue priority for a group member");
3089 }
3090
3091 BCMOLT_FIELD_SET(&member_info, group_member_info, egress_qos, egress_qos);
3092 BCMOLT_ARRAY_ELEM_SET(&(members), i, member_info);
3093 }
3094
3095 BCMOLT_OPER_INIT(&grp_mem_upd, group, members_update, key);
3096 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.members, members);
3097 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.command, grp_mem_upd_cmd);
3098
3099 err = bcmolt_oper_submit(dev_id, &(grp_mem_upd.hdr));
3100 bcmos_free(members.arr);
3101
3102 if (BCM_ERR_OK != err) {
3103 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);
3104 return bcm_to_grpc_err(err, "Failed to submit members update operation for the group");
3105 }
3106
3107 OPENOLT_LOG(INFO, openolt_log_id, "Successfully submitted members update operation for Group %d\n", key.id);
3108
3109 return Status::OK;
3110}
Burak Gurdageb4ca2e2020-06-15 07:48:26 +00003111
3112Status DeleteGroup_(uint32_t group_id) {
3113
3114 bcmos_errno err = BCM_ERR_OK;
3115 bcmolt_group_cfg grp_cfg_obj;
3116 bcmolt_group_key key = {};
3117
3118
3119 OPENOLT_LOG(INFO, openolt_log_id, "Delete request received for group %d\n", group_id);
3120
3121 if (group_id >= 0) {
3122 key.id = group_id;
3123 } else {
3124 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
3125 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
3126 }
3127
3128 /* init the BAL INIT API */
3129 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3130
3131 OPENOLT_LOG(DEBUG, openolt_log_id, "Checking if group %d exists...\n",group_id);
3132
3133 // CONFIGURE GROUP MEMBERS
3134 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
3135 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
3136
3137 if (err != BCM_ERR_OK) {
3138 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
3139 return bcm_to_grpc_err(err, "Error in querying group");
3140 }
3141
3142 if (grp_cfg_obj.data.state != BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
3143 OPENOLT_LOG(DEBUG, openolt_log_id, "Group %d exists. Will be deleted.\n",group_id);
3144 err = bcmolt_cfg_clear(dev_id, &(grp_cfg_obj.hdr));
3145 if (err != BCM_ERR_OK) {
3146 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d cannot be deleted err = %s (%d).\n", group_id, bcmos_strerror(err), err);
3147 return bcm_to_grpc_err(err, "Failed to delete group");;
3148 }
3149 } else {
3150 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d does not exist.\n", group_id);
3151 return Status(grpc::StatusCode::NOT_FOUND, "Group not found");
3152 }
3153
3154 OPENOLT_LOG(INFO, openolt_log_id, "Group %d has been deleted successfully.\n", group_id);
3155 return Status::OK;
Jason Huang1d9cfce2020-05-20 22:58:47 +08003156}
3157
Girish Gowdra252f4972020-09-07 21:24:01 -07003158Status GetLogicalOnuDistanceZero_(uint32_t intf_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003159 bcmos_errno err = BCM_ERR_OK;
3160 uint32_t mld = 0;
3161 double LD0;
3162
3163 err = getOnuMaxLogicalDistance(intf_id, &mld);
3164 if (err != BCM_ERR_OK) {
3165 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3166 }
3167
3168 LD0 = LOGICAL_DISTANCE(mld*1000, MINIMUM_ONU_RESPONSE_RANGING_TIME, ONU_BIT_TRANSMISSION_DELAY);
3169 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance zero is %f, (PON %d)\n", LD0, intf_id);
3170 response->set_intf_id(intf_id);
3171 response->set_logical_onu_distance_zero(LD0);
3172
3173 return Status::OK;
3174}
3175
Girish Gowdra252f4972020-09-07 21:24:01 -07003176Status GetLogicalOnuDistance_(uint32_t intf_id, uint32_t onu_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003177 bcmos_errno err = BCM_ERR_OK;
3178 bcmolt_itu_onu_params itu = {};
3179 bcmolt_onu_cfg onu_cfg;
3180 bcmolt_onu_key onu_key = {};
3181 uint32_t mld = 0;
3182 double LDi;
3183
3184 onu_key.pon_ni = intf_id;
3185 onu_key.onu_id = onu_id;
3186
3187 err = getOnuMaxLogicalDistance(intf_id, &mld);
3188 if (err != BCM_ERR_OK) {
3189 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3190 }
3191
3192 /* Initialize the API struct. */
3193 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
3194 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
3195 BCMOLT_FIELD_SET_PRESENT(&itu, itu_onu_params, ranging_time);
3196 BCMOLT_FIELD_SET(&onu_cfg.data, onu_cfg_data, itu, itu);
3197 #ifdef TEST_MODE
3198 // It is impossible to mock the setting of onu_cfg.data.onu_state because
3199 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
3200 // set the onu_cfg.data.onu_state. So a new stub function is created and address
3201 // of onu_cfg is passed. This is one-of case where we need to add test specific
3202 // code in production code.
3203 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
3204 #else
3205 /* Call API function. */
3206 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
3207 #endif
3208 if (err != BCM_ERR_OK) {
3209 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);
3210 return bcm_to_grpc_err(err, "Failed to retrieve ONU ranging time");
3211 }
3212
3213 if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_ACTIVE) {
3214 OPENOLT_LOG(ERROR, openolt_log_id, "ONU is not yet activated (PON %d, ONU id %d)\n", intf_id, onu_id);
3215 return bcm_to_grpc_err(BCM_ERR_PARM, "ONU is not yet activated\n");
3216 }
3217
3218 LDi = LOGICAL_DISTANCE(mld*1000, onu_cfg.data.itu.ranging_time, ONU_BIT_TRANSMISSION_DELAY);
3219 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance is %f, (PON %d, ONU id %d)\n", LDi, intf_id, onu_id);
3220 response->set_intf_id(intf_id);
3221 response->set_onu_id(onu_id);
3222 response->set_logical_onu_distance(LDi);
3223
3224 return Status::OK;
3225}
Burak Gurdag74e3ab82020-12-17 13:35:06 +00003226
3227Status GetOnuStatistics_(uint32_t intf_id, uint32_t onu_id, openolt::OnuStatistics* onu_stats) {
3228 bcmos_errno err;
3229
3230 err = get_onu_statistics((bcmolt_interface_id)intf_id, (bcmolt_onu_id)onu_id, onu_stats);
3231
3232 if (err != BCM_ERR_OK) {
3233 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));
3234 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of ONU statistics failed");
3235 }
3236
3237 OPENOLT_LOG(INFO, openolt_log_id, "retrieved ONU statistics for PON ID = %d, ONU ID = %d\n", (int)intf_id, (int)onu_id);
3238 return Status::OK;
3239}
3240
3241Status GetGemPortStatistics_(uint32_t intf_id, uint32_t gemport_id, openolt::GemPortStatistics* gemport_stats) {
3242 bcmos_errno err;
3243
3244 err = get_gemport_statistics((bcmolt_interface_id)intf_id, (bcmolt_gem_port_id)gemport_id, gemport_stats);
3245
3246 if (err != BCM_ERR_OK) {
3247 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));
3248 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of GEMPORT statistics failed");
3249 }
3250
3251 OPENOLT_LOG(INFO, openolt_log_id, "retrieved GEMPORT statistics for PON ID = %d, GEMPORT ID = %d\n", (int)intf_id, (int)gemport_id);
3252 return Status::OK;
3253}