blob: 8c2df06c7798ea23319e0d76d8a09138a2db6c4e [file] [log] [blame]
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001/*
Girish Gowdraa707e7c2019-11-07 11:36:13 +05302 * Copyright 2018-present Open Networking Foundation
Shad Ansarib7b0ced2018-05-11 21:53:32 +00003
Girish Gowdraa707e7c2019-11-07 11:36:13 +05304 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
Shad Ansarib7b0ced2018-05-11 21:53:32 +00007
Girish Gowdraa707e7c2019-11-07 11:36:13 +05308 * http://www.apache.org/licenses/LICENSE-2.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00009
Girish Gowdraa707e7c2019-11-07 11:36:13 +053010 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +000016
17#include <iostream>
18#include <memory>
19#include <string>
20
21#include "Queue.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000022#include <sstream>
Nicolas Palpacuer9c352082018-08-14 16:37:14 -040023#include <chrono>
24#include <thread>
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080025#include <bitset>
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000026#include <inttypes.h>
Jason Huangbf45ffb2019-10-30 17:29:02 +080027#include <unistd.h>
Jason Huang09b73ea2020-01-08 17:52:05 +080028#include <sys/socket.h>
29#include <netinet/in.h>
30#include <arpa/inet.h>
Shad Ansarib7b0ced2018-05-11 21:53:32 +000031
Craig Lutgen88a22ad2018-10-04 12:30:46 -050032#include "device.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000033#include "core.h"
Girish Gowdraddf9a162020-01-27 12:56:27 +053034#include "core_data.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000035#include "indications.h"
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -040036#include "stats_collection.h"
Nicolas Palpacuer73222e02018-07-16 12:20:26 -040037#include "error_format.h"
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -040038#include "state.h"
Girish Gowdraddf9a162020-01-27 12:56:27 +053039#include "core_utils.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000040
41extern "C"
42{
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000043#include <bcmolt_api.h>
44#include <bcmolt_host_api.h>
45#include <bcmolt_api_model_supporting_enums.h>
46
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000047#include <bcmolt_api_conn_mgr.h>
48//CLI header files
49#include <bcmcli_session.h>
50#include <bcmcli.h>
51#include <bcm_api_cli.h>
52
53#include <bcmos_common.h>
54#include <bcm_config.h>
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -040055// FIXME : dependency problem
56// #include <bcm_common_gpon.h>
Nicolas Palpacuer967438f2018-09-07 14:41:54 -040057// #include <bcm_dev_log_task.h>
Shad Ansarib7b0ced2018-05-11 21:53:32 +000058}
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000059
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000060static std::string intf_technologies[MAX_SUPPORTED_PON];
Craig Lutgen88a22ad2018-10-04 12:30:46 -050061static const std::string UNKNOWN_TECH("unknown");
Craig Lutgenb2601f02018-10-23 13:04:31 -050062static const std::string MIXED_TECH("mixed");
63static std::string board_technology(UNKNOWN_TECH);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000064static std::string chip_family(UNKNOWN_TECH);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000065static std::string firmware_version = "Openolt.2019.07.01";
Nicolas Palpacuerdff96792018-09-06 14:59:32 -040066
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080067static bcmos_errno CreateSched(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
Girish Gowdra252f4972020-09-07 21:24:01 -070068 uint32_t port_no, uint32_t alloc_id, ::tech_profile::AdditionalBW additional_bw, uint32_t weight, \
69 uint32_t priority, ::tech_profile::SchedulingPolicy sched_policy,
70 ::tech_profile::TrafficShapingInfo traffic_shaping_info, uint32_t tech_profile_id);
Burak Gurdag2f2618c2020-04-23 13:20:30 +000071static bcmos_errno RemoveSched(int intf_id, int onu_id, int uni_id, int alloc_id, std::string direction, int tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080072static bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +000073 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id, uint32_t tech_profile_id);
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -050074static bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +000075 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id, uint32_t tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000076static bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction);
77static bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction);
78
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000079inline const char *get_flow_acton_command(uint32_t command) {
80 char actions[200] = { };
81 char *s_actions_ptr = actions;
82 if (command & BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG) strcat(s_actions_ptr, "ADD_OUTER_TAG|");
83 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG) strcat(s_actions_ptr, "REMOVE_OUTER_TAG|");
84 if (command & BCMOLT_ACTION_CMD_ID_XLATE_OUTER_TAG) strcat(s_actions_ptr, "TRANSLATE_OUTER_TAG|");
85 if (command & BCMOLT_ACTION_CMD_ID_ADD_INNER_TAG) strcat(s_actions_ptr, "ADD_INNTER_TAG|");
86 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_INNER_TAG) strcat(s_actions_ptr, "REMOVE_INNER_TAG|");
87 if (command & BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG) strcat(s_actions_ptr, "TRANSLATE_INNER_TAG|");
88 if (command & BCMOLT_ACTION_CMD_ID_REMARK_OUTER_PBITS) strcat(s_actions_ptr, "REMOVE_OUTER_PBITS|");
89 if (command & BCMOLT_ACTION_CMD_ID_REMARK_INNER_PBITS) strcat(s_actions_ptr, "REMAKE_INNER_PBITS|");
90 return s_actions_ptr;
91}
92
kesavandc1f2db92020-08-31 15:32:06 +053093bcmolt_stat_alarm_config set_stat_alarm_config(const config::OnuItuPonAlarm* request) {
Jason Huang5d9ab1a2020-04-15 16:53:49 +080094 bcmolt_stat_alarm_config alarm_cfg = {};
95 bcmolt_stat_alarm_trigger_config trigger_obj = {};
96 bcmolt_stat_alarm_soak_config soak_obj = {};
97
98 switch (request->alarm_reporting_condition()) {
kesavandc1f2db92020-08-31 15:32:06 +053099 case config::OnuItuPonAlarm::RATE_THRESHOLD:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800100 trigger_obj.type = BCMOLT_STAT_CONDITION_TYPE_RATE_THRESHOLD;
101 BCMOLT_FIELD_SET(&trigger_obj.u.rate_threshold, stat_alarm_trigger_config_rate_threshold,
102 rising, request->rate_threshold_config().rate_threshold_rising());
103 BCMOLT_FIELD_SET(&trigger_obj.u.rate_threshold, stat_alarm_trigger_config_rate_threshold,
104 falling, request->rate_threshold_config().rate_threshold_falling());
105 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, active_soak_time,
106 request->rate_threshold_config().soak_time().active_soak_time());
107 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, clear_soak_time,
108 request->rate_threshold_config().soak_time().clear_soak_time());
109 break;
kesavandc1f2db92020-08-31 15:32:06 +0530110 case config::OnuItuPonAlarm::RATE_RANGE:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800111 trigger_obj.type = BCMOLT_STAT_CONDITION_TYPE_RATE_RANGE;
112 BCMOLT_FIELD_SET(&trigger_obj.u.rate_range, stat_alarm_trigger_config_rate_range, upper,
113 request->rate_range_config().rate_range_upper());
114 BCMOLT_FIELD_SET(&trigger_obj.u.rate_range, stat_alarm_trigger_config_rate_range, lower,
115 request->rate_range_config().rate_range_lower());
116 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, active_soak_time,
117 request->rate_range_config().soak_time().active_soak_time());
118 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, clear_soak_time,
119 request->rate_range_config().soak_time().clear_soak_time());
120 break;
kesavandc1f2db92020-08-31 15:32:06 +0530121 case config::OnuItuPonAlarm::VALUE_THRESHOLD:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800122 trigger_obj.type = BCMOLT_STAT_CONDITION_TYPE_VALUE_THRESHOLD;
123 BCMOLT_FIELD_SET(&trigger_obj.u.value_threshold, stat_alarm_trigger_config_value_threshold,
124 limit, request->value_threshold_config().threshold_limit());
125 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, active_soak_time,
126 request->value_threshold_config().soak_time().active_soak_time());
127 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, clear_soak_time,
128 request->value_threshold_config().soak_time().clear_soak_time());
129 break;
130 default:
131 OPENOLT_LOG(ERROR, openolt_log_id, "unsupported alarm reporting condition = %u\n", request->alarm_reporting_condition());
132 // For now just log the error and not return error. We can handle this scenario in the future.
133 break;
134 }
135
136 BCMOLT_FIELD_SET(&alarm_cfg, stat_alarm_config, trigger, trigger_obj);
137 BCMOLT_FIELD_SET(&alarm_cfg, stat_alarm_config, soak, soak_obj);
138
139 return alarm_cfg;
140}
141
kesavandc1f2db92020-08-31 15:32:06 +0530142Status OnuItuPonAlarmSet_(const config::OnuItuPonAlarm* request) {
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800143 bcmos_errno err;
144 bcmolt_onu_itu_pon_stats_cfg stat_cfg; /* declare main API struct */
145 bcmolt_onu_key key = {}; /* declare key */
146 bcmolt_stat_alarm_config errors_cfg = {};
147
148 key.pon_ni = request->pon_ni();
149 key.onu_id = request->onu_id();
150
151 /* Initialize the API struct. */
152 BCMOLT_STAT_CFG_INIT(&stat_cfg, onu, itu_pon_stats, key);
153
154 /*
155 1. BCMOLT_STAT_CONDITION_TYPE_NONE = 0, The alarm is disabled.
156 2. BCMOLT_STAT_CONDITION_TYPE_RATE_THRESHOLD = 1, The alarm is triggered if the stats delta value between samples
157 crosses the configured threshold boundary.
158 rising: The alarm is raised if the stats delta value per second becomes greater than this threshold level.
159 falling: The alarm is cleared if the stats delta value per second becomes less than this threshold level.
160 3. BCMOLT_STAT_CONDITION_TYPE_RATE_RANGE = 2, The alarm is triggered if the stats delta value between samples
161 deviates from the configured range.
162 upper: The alarm is raised if the stats delta value per second becomes greater than this upper level.
163 lower: The alarm is raised if the stats delta value per second becomes less than this lower level.
164 4. BCMOLT_STAT_CONDITION_TYPE_VALUE_THRESHOLD = 3, The alarm is raised if the stats sample value becomes greater
165 than this level. The alarm is cleared when the host read the stats.
166 limit: The alarm is raised if the stats sample value becomes greater than this level.
167 The alarm is cleared when the host clears the stats.
168
169 active_soak_time: If the alarm condition is raised and stays in the raised state for at least this amount
170 of time (unit=seconds), the alarm indication is sent to the host.
171 The OLT delays the alarm indication no less than this delay period.
172 It can be delayed more than this period because of the statistics sampling interval.
173 clear_soak_time: After the alarm is raised, if it is cleared and stays in the cleared state for at least
174 this amount of time (unit=seconds), the alarm indication is sent to the host.
175 The OLT delays the alarm indication no less than this delay period. It can be delayed more
176 than this period because of the statistics sampling interval.
177 */
178
179 errors_cfg = set_stat_alarm_config(request);
180
181 switch (request->alarm_id()) {
kesavandc1f2db92020-08-31 15:32:06 +0530182 case config::OnuItuPonAlarm_AlarmID::OnuItuPonAlarm_AlarmID_RDI_ERRORS:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800183 //set the rdi_errors alarm
184 BCMOLT_FIELD_SET(&stat_cfg.data, onu_itu_pon_stats_cfg_data, rdi_errors, errors_cfg);
185 break;
186 default:
187 OPENOLT_LOG(ERROR, openolt_log_id, "could not find the alarm id %d\n", request->alarm_id());
188 return bcm_to_grpc_err(BCM_ERR_PARM, "the alarm id is wrong");
189 }
190
191 err = bcmolt_stat_cfg_set(dev_id, &stat_cfg.hdr);
192 if (err != BCM_ERR_OK) {
193 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to set onu itu pon stats, alarm id %d, pon_ni %d, onu_id %d, err = %s\n",
194 request->alarm_id(), key.pon_ni, key.onu_id, bcmos_strerror(err));
195 return bcm_to_grpc_err(err, "set Onu ITU PON stats alarm faild");
196 } else {
197 OPENOLT_LOG(INFO, openolt_log_id, "set onu itu pon stats alarm %d successfully, pon_ni %d, onu_id %d\n",
198 request->alarm_id(), key.pon_ni, key.onu_id);
199 }
200
201 return Status::OK;
202}
203
Girish Gowdra252f4972020-09-07 21:24:01 -0700204Status GetDeviceInfo_(::openolt::DeviceInfo* device_info) {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500205 device_info->set_vendor(VENDOR_ID);
206 device_info->set_model(MODEL_ID);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400207 device_info->set_hardware_version("");
208 device_info->set_firmware_version(firmware_version);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500209 device_info->set_technology(board_technology);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500210 device_info->set_pon_ports(num_of_pon_ports);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500211
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800212 char serial_number[OPENOLT_FIELD_LEN];
213 memset(serial_number, '\0', OPENOLT_FIELD_LEN);
214 openolt_read_sysinfo("Serial Number", serial_number);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000215 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device serial number %s\n", serial_number);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800216 device_info->set_device_serial_number(serial_number);
217
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700218 char device_id[OPENOLT_FIELD_LEN];
219 memset(device_id, '\0', OPENOLT_FIELD_LEN);
Humera Kouser6143c9e2020-06-17 22:37:31 +0530220
221 if (grpc_server_interface_name != NULL) {
222 if (get_intf_mac(grpc_server_interface_name, device_id, sizeof(device_id)) != NULL)
223 {
224 OPENOLT_LOG(INFO, openolt_log_id, "Fetched mac address %s of an interface %s\n", device_id, grpc_server_interface_name);
225 }
226 else
227 {
228 OPENOLT_LOG(ERROR, openolt_log_id, "Mac address of an interface %s is NULL\n", grpc_server_interface_name);
229 }
230 }
231 else
232 {
233 openolt_read_sysinfo("MAC", device_id);
234 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device mac address %s\n", device_id);
235 }
236
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700237 device_info->set_device_id(device_id);
238
Craig Lutgenb2601f02018-10-23 13:04:31 -0500239 // Legacy, device-wide ranges. To be deprecated when adapter
240 // is upgraded to support per-interface ranges
Girish Gowdra252f4972020-09-07 21:24:01 -0700241 device_info->set_onu_id_start(ONU_ID_START);
242 device_info->set_onu_id_end(ONU_ID_END);
243 device_info->set_alloc_id_start(ALLOC_ID_START);
244 device_info->set_alloc_id_end(ALLOC_ID_END);
245 device_info->set_gemport_id_start(GEM_PORT_ID_START);
246 device_info->set_gemport_id_end(GEM_PORT_ID_END);
247 device_info->set_flow_id_start(FLOW_ID_START);
248 device_info->set_flow_id_end(FLOW_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500249
Girish Gowdra252f4972020-09-07 21:24:01 -0700250 std::map<std::string, ::openolt::DeviceInfo::DeviceResourceRanges*> ranges;
Craig Lutgenb2601f02018-10-23 13:04:31 -0500251 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
252 std::string intf_technology = intf_technologies[intf_id];
Girish Gowdra252f4972020-09-07 21:24:01 -0700253 ::openolt::DeviceInfo::DeviceResourceRanges *range = ranges[intf_technology];
Craig Lutgenb2601f02018-10-23 13:04:31 -0500254 if(range == nullptr) {
255 range = device_info->add_ranges();
256 ranges[intf_technology] = range;
257 range->set_technology(intf_technology);
258
Girish Gowdra252f4972020-09-07 21:24:01 -0700259 ::openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
Craig Lutgenb2601f02018-10-23 13:04:31 -0500260
Girish Gowdra252f4972020-09-07 21:24:01 -0700261 pool = range->add_pools();
262 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
263 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
264 pool->set_start(ONU_ID_START);
265 pool->set_end(ONU_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500266
Girish Gowdra252f4972020-09-07 21:24:01 -0700267 pool = range->add_pools();
268 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
269 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
270 pool->set_start(ALLOC_ID_START);
271 pool->set_end(ALLOC_ID_START);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500272
Girish Gowdra252f4972020-09-07 21:24:01 -0700273 pool = range->add_pools();
274 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
275 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
276 pool->set_start(GEM_PORT_ID_START);
277 pool->set_end(GEM_PORT_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500278
Girish Gowdra252f4972020-09-07 21:24:01 -0700279 pool = range->add_pools();
280 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
281 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
282 pool->set_start(FLOW_ID_START);
283 pool->set_end(FLOW_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500284 }
285
286 range->add_intf_ids(intf_id);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500287 }
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400288
289 // FIXME: Once dependency problem is fixed
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500290 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400291 // device_info->set_onu_id_end(XGPON_NUM_OF_ONUS - 1);
292 // device_info->set_alloc_id_start(1024);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500293 // device_info->set_alloc_id_end(XGPON_NUM_OF_ALLOC_IDS * num_of_pon_ports ? - 1);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400294 // device_info->set_gemport_id_start(XGPON_MIN_BASE_SERVICE_PORT_ID);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500295 // device_info->set_gemport_id_end(XGPON_NUM_OF_GEM_PORT_IDS_PER_PON * num_of_pon_ports ? - 1);
296 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400297
298 return Status::OK;
299}
300
Shad Ansari627b5782018-08-13 22:49:32 +0000301Status Enable_(int argc, char *argv[]) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000302 bcmos_errno err;
303 bcmolt_host_init_parms init_parms = {};
304 init_parms.transport.type = BCM_HOST_API_CONN_LOCAL;
305 unsigned int failed_enable_device_cnt = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000306
Shad Ansariedef2132018-08-10 22:14:50 +0000307 if (!state.is_activated()) {
Shad Ansari627b5782018-08-13 22:49:32 +0000308
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500309 vendor_init();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000310 /* Initialize host subsystem */
311 err = bcmolt_host_init(&init_parms);
312 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500313 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to init OLT, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000314 return bcm_to_grpc_err(err, "Failed to init OLT");
315 }
316
317 bcmcli_session_parm mon_session_parm;
318 /* Create CLI session */
319 memset(&mon_session_parm, 0, sizeof(mon_session_parm));
320 mon_session_parm.get_prompt = openolt_cli_get_prompt_cb;
321 mon_session_parm.access_right = BCMCLI_ACCESS_ADMIN;
322 bcmos_errno rc = bcmcli_session_open(&mon_session_parm, &current_session);
323 BUG_ON(rc != BCM_ERR_OK);
324
325 /* API CLI */
326 bcm_openolt_api_cli_init(NULL, current_session);
327
328 /* Add quit command */
329 BCMCLI_MAKE_CMD_NOPARM(NULL, "quit", "Quit", bcm_cli_quit);
330
331 err = bcmolt_apiend_cli_init();
332 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500333 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to add apiend init, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000334 return bcm_to_grpc_err(err, "Failed to add apiend init");
335 }
336
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800337 bcmos_fastlock_init(&data_lock, 0);
Girish Gowdra252f4972020-09-07 21:24:01 -0700338 bcmos_fastlock_init(&acl_id_bitset_lock, 0);
339 bcmos_fastlock_init(&tm_sched_bitset_lock, 0);
340 bcmos_fastlock_init(&tm_qmp_bitset_lock, 0);
341 bcmos_fastlock_init(&flow_id_bitset_lock, 0);
342 bcmos_fastlock_init(&voltha_flow_to_device_flow_lock, 0);
Girish Gowdra96461052019-11-22 20:13:59 +0530343 bcmos_fastlock_init(&alloc_cfg_wait_lock, 0);
Girish Gowdra7a79dae2020-02-10 18:22:11 +0530344 bcmos_fastlock_init(&onu_deactivate_wait_lock, 0);
Girish Gowdra1935e6a2020-10-31 21:48:22 -0700345 bcmos_fastlock_init(&acl_packet_trap_handler_lock, 0);
346
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000347 OPENOLT_LOG(INFO, openolt_log_id, "Enable OLT - %s-%s\n", VENDOR_ID, MODEL_ID);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600348
Jason Huangbf45ffb2019-10-30 17:29:02 +0800349 //check BCM daemon is connected or not
350 Status status = check_connection();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000351 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800352 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000353 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800354 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000355 Status status = SubscribeIndication();
356 if (!status.ok()) {
357 OPENOLT_LOG(ERROR, openolt_log_id, "SubscribeIndication failed - %s : %s\n",
358 grpc_status_code_to_string(status.error_code()).c_str(),
359 status.error_message().c_str());
360 return status;
361 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800362
363 //check BAL state in initial stage
364 status = check_bal_ready();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000365 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800366 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000367 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800368 }
369
370 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000371 bcmos_errno err;
372 bcmolt_odid dev;
373 OPENOLT_LOG(INFO, openolt_log_id, "Enabling PON %d Devices ... \n", BCM_MAX_DEVS_PER_LINE_CARD);
374 for (dev = 0; dev < BCM_MAX_DEVS_PER_LINE_CARD; dev++) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400375 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000376 bcmolt_device_key dev_key = { };
377 dev_key.device_id = dev;
378 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
379 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
380 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
Jason Huangbf45ffb2019-10-30 17:29:02 +0800381 if (err == BCM_ERR_NOT_CONNECTED) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000382 bcmolt_device_key key = {.device_id = dev};
383 bcmolt_device_connect oper;
384 BCMOLT_OPER_INIT(&oper, device, connect, key);
385 if (MODEL_ID == "asfvolt16") {
386 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
387 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_XGS__2_X);
388 } else if (MODEL_ID == "asgvolt64") {
389 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
390 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
391 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
392 }
393 err = bcmolt_oper_submit(dev_id, &oper.hdr);
394 if (err) {
395 failed_enable_device_cnt ++;
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500396 OPENOLT_LOG(ERROR, openolt_log_id, "Enable PON device %d failed, err = %s\n", dev, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000397 if (failed_enable_device_cnt == BCM_MAX_DEVS_PER_LINE_CARD) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500398 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to enable all the pon ports, err = %s\n", bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000399 return Status(grpc::StatusCode::INTERNAL, "Failed to activate all PON ports");
400 }
401 }
402 bcmos_usleep(200000);
403 }
404 else {
405 OPENOLT_LOG(WARNING, openolt_log_id, "PON deivce %d already connected\n", dev);
406 state.activate();
407 }
408 }
409 init_stats();
Shad Ansari627b5782018-08-13 22:49:32 +0000410 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000411 }
Shad Ansariedef2132018-08-10 22:14:50 +0000412
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000413 /* Start CLI */
414 OPENOLT_LOG(INFO, def_log_id, "Starting CLI\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400415 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000416 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400417}
418
419Status Disable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400420 //In the earlier implementation Disabling olt is done by disabling the NNI port associated with that.
421 //In inband scenario instead of using management interface to establish connection with adapter ,NNI interface will be used.
422 //Disabling NNI port on olt disable causes connection loss between adapter and agent.
423 //To overcome this disable is implemented by disabling all the PON ports
424 //associated with the device so as to support both in-band
425 //and out of band scenarios.
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400426
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400427 Status status;
428 int failedCount = 0;
429 for (int i = 0; i < NumPonIf_(); i++) {
430 status = DisablePonIf_(i);
431 if (!status.ok()) {
432 failedCount+=1;
433 BCM_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", i);
434 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400435 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400436 if (failedCount == 0) {
437 state.deactivate();
Girish Gowdra252f4972020-09-07 21:24:01 -0700438 ::openolt::Indication ind;
439 ::openolt::OltIndication* olt_ind = new ::openolt::OltIndication;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400440 olt_ind->set_oper_state("down");
441 ind.set_allocated_olt_ind(olt_ind);
442 BCM_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
443 oltIndQ.push(ind);
444 return Status::OK;
445 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000446 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400447 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to disable olt ,all the PON ports are still in enabled state");
448 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400449
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400450 return grpc::Status(grpc::StatusCode::UNKNOWN, "failed to disable olt ,few PON ports are still in enabled state");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400451}
452
453Status Reenable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400454 Status status;
455 int failedCount = 0;
456 for (int i = 0; i < NumPonIf_(); i++) {
457 status = EnablePonIf_(i);
458 if (!status.ok()) {
459 failedCount+=1;
460 BCM_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", i);
461 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400462 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000463 if (failedCount == 0) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400464 state.activate();
Girish Gowdra252f4972020-09-07 21:24:01 -0700465 ::openolt::Indication ind;
466 ::openolt::OltIndication* olt_ind = new ::openolt::OltIndication;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400467 olt_ind->set_oper_state("up");
468 ind.set_allocated_olt_ind(olt_ind);
469 BCM_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
470 oltIndQ.push(ind);
471 return Status::OK;
472 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000473 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400474 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to re-enable olt ,all the PON ports are still in disabled state");
475 }
476 return grpc::Status(grpc::StatusCode::UNKNOWN, "failed to re-enable olt ,few PON ports are still in disabled state");
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000477}
478
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000479inline uint64_t get_flow_status(uint16_t flow_id, uint16_t flow_type, uint16_t data_id) {
480 bcmos_errno err;
481 bcmolt_flow_key flow_key;
482 bcmolt_flow_cfg flow_cfg;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400483
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000484 flow_key.flow_id = flow_id;
485 flow_key.flow_type = (bcmolt_flow_type)flow_type;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400486
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000487 BCMOLT_CFG_INIT(&flow_cfg, flow, flow_key);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400488
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000489 switch (data_id) {
490 case ONU_ID: //onu_id
491 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, onu_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500492 #ifdef TEST_MODE
493 // It is impossible to mock the setting of flow_cfg.data.state because
494 // the actual bcmolt_cfg_get passes the address of flow_cfg.hdr and we cannot
495 // set the flow_cfg.data. So a new stub function is created and address
496 // of flow_cfg is passed. This is one-of case where we need to add test specific
497 // code in production code.
498 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
499 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000500 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500501 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000502 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500503 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get onu_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000504 return err;
505 }
506 return flow_cfg.data.onu_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400507 case FLOW_TYPE:
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500508 #ifdef TEST_MODE
509 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
510 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000511 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500512 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000513 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500514 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get flow_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000515 return err;
516 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400517 return flow_cfg.key.flow_type;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000518 case SVC_PORT_ID: //svc_port_id
519 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, svc_port_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500520 #ifdef TEST_MODE
521 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
522 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000523 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500524 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000525 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500526 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get svc_port_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000527 return err;
528 }
529 return flow_cfg.data.svc_port_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400530 case PRIORITY:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000531 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, priority);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500532 #ifdef TEST_MODE
533 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
534 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000535 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500536 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000537 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500538 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get priority, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000539 return err;
540 }
541 return flow_cfg.data.priority;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400542 case COOKIE: //cookie
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000543 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, cookie);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500544 #ifdef TEST_MODE
545 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
546 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000547 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500548 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000549 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500550 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get cookie, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000551 return err;
552 }
553 return flow_cfg.data.cookie;
554 case INGRESS_INTF_TYPE: //ingress intf_type
555 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500556 #ifdef TEST_MODE
557 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
558 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000559 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500560 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000561 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500562 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get ingress intf_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000563 return err;
564 }
565 return flow_cfg.data.ingress_intf.intf_type;
566 case EGRESS_INTF_TYPE: //egress intf_type
567 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500568 #ifdef TEST_MODE
569 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
570 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000571 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500572 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000573 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500574 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress intf_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000575 return err;
576 }
577 return flow_cfg.data.egress_intf.intf_type;
578 case INGRESS_INTF_ID: //ingress intf_id
579 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500580 #ifdef TEST_MODE
581 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
582 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000583 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500584 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000585 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500586 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get ingress intf_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000587 return err;
588 }
589 return flow_cfg.data.ingress_intf.intf_id;
590 case EGRESS_INTF_ID: //egress intf_id
591 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500592 #ifdef TEST_MODE
593 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
594 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000595 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500596 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000597 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500598 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress intf_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000599 return err;
600 }
601 return flow_cfg.data.egress_intf.intf_id;
602 case CLASSIFIER_O_VID:
603 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500604 #ifdef TEST_MODE
605 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
606 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000607 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500608 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000609 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500610 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier o_vid, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000611 return err;
612 }
613 return flow_cfg.data.classifier.o_vid;
614 case CLASSIFIER_O_PBITS:
615 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500616 #ifdef TEST_MODE
617 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
618 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000619 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500620 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000621 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500622 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier o_pbits, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000623 return err;
624 }
625 return flow_cfg.data.classifier.o_pbits;
626 case CLASSIFIER_I_VID:
627 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500628 #ifdef TEST_MODE
629 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
630 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000631 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500632 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000633 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500634 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier i_vid, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000635 return err;
636 }
637 return flow_cfg.data.classifier.i_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400638 case CLASSIFIER_I_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000639 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500640 #ifdef TEST_MODE
641 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
642 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000643 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500644 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000645 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500646 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier i_pbits, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000647 return err;
648 }
649 return flow_cfg.data.classifier.i_pbits;
650 case CLASSIFIER_ETHER_TYPE:
651 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500652 #ifdef TEST_MODE
653 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
654 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000655 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500656 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000657 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500658 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier ether_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000659 return err;
660 }
661 return flow_cfg.data.classifier.ether_type;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400662 case CLASSIFIER_IP_PROTO:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000663 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500664 #ifdef TEST_MODE
665 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
666 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000667 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500668 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000669 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500670 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier ip_proto, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000671 return err;
672 }
673 return flow_cfg.data.classifier.ip_proto;
674 case CLASSIFIER_SRC_PORT:
675 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500676 #ifdef TEST_MODE
677 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
678 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000679 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500680 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000681 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500682 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier src_port, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000683 return err;
684 }
685 return flow_cfg.data.classifier.src_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400686 case CLASSIFIER_DST_PORT:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000687 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500688 #ifdef TEST_MODE
689 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
690 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000691 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500692 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000693 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500694 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier dst_port, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000695 return err;
696 }
697 return flow_cfg.data.classifier.dst_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400698 case CLASSIFIER_PKT_TAG_TYPE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000699 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500700 #ifdef TEST_MODE
701 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
702 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000703 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500704 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000705 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500706 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier pkt_tag_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000707 return err;
708 }
709 return flow_cfg.data.classifier.pkt_tag_type;
710 case EGRESS_QOS_TYPE:
711 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500712 #ifdef TEST_MODE
713 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
714 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000715 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500716 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000717 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500718 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000719 return err;
720 }
721 return flow_cfg.data.egress_qos.type;
722 case EGRESS_QOS_QUEUE_ID:
723 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500724 #ifdef TEST_MODE
725 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
726 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000727 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500728 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000729 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500730 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos queue_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000731 return err;
732 }
733 switch (flow_cfg.data.egress_qos.type) {
734 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE:
735 return flow_cfg.data.egress_qos.u.fixed_queue.queue_id;
736 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE:
737 return flow_cfg.data.egress_qos.u.tc_to_queue.tc_to_queue_id;
738 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC:
739 return flow_cfg.data.egress_qos.u.pbit_to_tc.tc_to_queue_id;
740 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE:
741 return flow_cfg.data.egress_qos.u.priority_to_queue.tm_q_set_id;
742 case BCMOLT_EGRESS_QOS_TYPE_NONE:
743 default:
744 return -1;
745 }
746 case EGRESS_QOS_TM_SCHED_ID:
747 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500748 #ifdef TEST_MODE
749 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
750 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000751 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500752 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000753 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500754 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos tm_sched_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000755 return err;
756 }
757 return flow_cfg.data.egress_qos.tm_sched.id;
758 case ACTION_CMDS_BITMASK:
759 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500760 #ifdef TEST_MODE
761 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
762 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000763 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500764 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000765 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500766 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action cmds_bitmask, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000767 return err;
768 }
769 return flow_cfg.data.action.cmds_bitmask;
770 case ACTION_O_VID:
771 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500772 #ifdef TEST_MODE
773 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
774 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000775 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500776 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000777 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500778 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action o_vid, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000779 return err;
780 }
781 return flow_cfg.data.action.o_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400782 case ACTION_O_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000783 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500784 #ifdef TEST_MODE
785 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
786 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000787 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500788 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000789 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500790 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action o_pbits, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000791 return err;
792 }
793 return flow_cfg.data.action.o_pbits;
794 case ACTION_I_VID:
795 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500796 #ifdef TEST_MODE
797 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
798 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000799 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500800 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000801 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500802 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action i_vid, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000803 return err;
804 }
805 return flow_cfg.data.action.i_vid;
806 case ACTION_I_PBITS:
807 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500808 #ifdef TEST_MODE
809 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
810 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000811 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500812 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000813 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500814 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action i_pbits, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000815 return err;
816 }
817 return flow_cfg.data.action.i_pbits;
818 case STATE:
819 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, state);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500820 #ifdef TEST_MODE
821 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
822 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000823 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500824 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000825 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500826 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get state, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000827 return err;
828 }
829 return flow_cfg.data.state;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000830 case GROUP_ID:
831 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, group_id);
832 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
833 if (err) {
834 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get group_id, err = %s\n",bcmos_strerror(err));
835 return err;
836 }
837 return flow_cfg.data.group_id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000838 default:
839 return BCM_ERR_INTERNAL;
840 }
841
842 return err;
843}
844
845Status EnablePonIf_(uint32_t intf_id) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400846 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000847 bcmolt_pon_interface_cfg interface_obj;
848 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
849 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
850 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530851 bcmolt_status los_status;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000852
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530853 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000854 if (err == BCM_ERR_OK) {
855 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800856 OPENOLT_LOG(WARNING, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000857 return Status::OK;
858 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400859 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000860 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
861 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
862 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
863 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.interval, 5000);
864 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.onu_post_discovery_mode,
Girish Gowdra24297032020-03-23 12:32:37 -0700865 BCMOLT_ONU_POST_DISCOVERY_MODE_NONE);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000866 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.los, true);
867 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.onu_alarms, true);
868 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.tiwi, true);
869 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.ack_timeout, true);
870 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.sfi, true);
871 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.loki, true);
Burak Gurdag5e587792020-05-06 14:58:02 +0000872
873 // On GPON, power level mode is not set to its default value (i.e. 0) as documented in Broadcom documentation.
874 // Instead, it is set to 2 which means -6 dbM attenuation. Therefore, we explicitly set it to the default value below.
875 if (board_technology == "GPON") {
876 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.pls_maximum_allocation_size, BCMOLT_PON_POWER_LEVEL_PLS_MAXIMUM_ALLOCATION_SIZE_DEFAULT);
877 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.mode, BCMOLT_PON_POWER_LEVEL_MODE_DEFAULT);
878 }
879
kesavandc1f2db92020-08-31 15:32:06 +0530880 //Enable AES Encryption
881 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.key_exchange, BCMOLT_CONTROL_STATE_ENABLE);
882 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.authentication, BCMOLT_CONTROL_STATE_ENABLE);
883 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.fail_due_to_authentication_failure, BCMOLT_CONTROL_STATE_ENABLE);
884
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000885 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
886 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
887
888 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
889 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500890 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to enable discovery onu, PON interface %d, err = %s\n", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000891 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
892 }
893 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
894 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500895 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d, err = %s\n", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000896 return bcm_to_grpc_err(err, "Failed to enable PON interface");
897 }
898 else {
899 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
900 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
901 CreateDefaultSched(intf_id, downstream);
902 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400903 }
904
905 return Status::OK;
906}
907
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500908Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000909 bcmos_errno err;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400910 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000911 bcmolt_device_key dev_key = { };
912 bcmolt_olt_cfg olt_cfg = { };
913 bcmolt_olt_key olt_key = { };
914 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
915 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500916
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000917 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
918 topo.topology_maps.arr = &topo_map[0];
919 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
920 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
921 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400922 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000923 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400924 #ifdef TEST_MODE
925 // It is impossible to mock the setting of olt_cfg.data.bal_state because
926 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
927 // set the olt_cfg.data.topology. So a new stub function is created and address
928 // of olt_cfg is passed. This is one-of case where we need to test add specific
929 // code in production code.
930 err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
931 #else
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000932 err = bcmolt_cfg_get_mult_retry(dev_id, &olt_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400933 #endif
934 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500935 OPENOLT_LOG(ERROR, openolt_log_id, "cfg: Failed to query OLT topology, err = %s\n", bcmos_strerror(err));
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000936 return bcm_to_grpc_err(err, "cfg: Failed to query OLT topology");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500937 }
938
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000939 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
940 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500941
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400942 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
943 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000944 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500945
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000946 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
947 num_of_nni_ports,
948 num_of_pon_ports,
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400949 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500950
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000951 uint32_t num_failed_cfg_gets = 0;
Jason Huang09b73ea2020-01-08 17:52:05 +0800952 static std::string openolt_version = firmware_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000953 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
954 dev_key.device_id = devid;
955 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
956 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
957 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
958 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000959 err = bcmolt_cfg_get_mult_retry(dev_id, &dev_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400960 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500961 OPENOLT_LOG(WARNING, openolt_log_id,"Failed to query PON MAC Device %d (errno = %s). Skipping the device.\n", devid, bcmos_strerror(err));
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000962 num_failed_cfg_gets++;
963 continue;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000964 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500965
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000966 std::string bal_version;
967 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
968 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
969 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
Jason Huang09b73ea2020-01-08 17:52:05 +0800970 firmware_version = "BAL." + bal_version + "__" + openolt_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000971
972 switch(dev_cfg.data.system_mode) {
973 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
974 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
975 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
976 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
977 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
978 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
979 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
980 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
981 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
982 case 20: board_technology = MIXED_TECH; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,MIXED_TECH); break;
983 }
984
985 switch(dev_cfg.data.chip_family) {
Jason Huang09b73ea2020-01-08 17:52:05 +0800986 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X: chip_family = "Maple"; break;
987 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X: chip_family = "Aspen"; break;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000988 }
989
Jason Huang09b73ea2020-01-08 17:52:05 +0800990 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s, family: %s, board_technology: %s\n",
991 devid, BCM_MAX_PONS_PER_DEV, bal_version.c_str(), chip_family.c_str(), board_technology.c_str());
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000992
993 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500994 }
995
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000996 /* If all the devices returned errors then we tell the caller that this is an error else we work with
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000997 only the devices that retured success*/
998 if (num_failed_cfg_gets == BCM_MAX_DEVS_PER_LINE_CARD) {
999 OPENOLT_LOG(ERROR, openolt_log_id, "device: Query of all the devices failed\n");
1000 return bcm_to_grpc_err(err, "device: All devices failed query");
1001 }
1002
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001003 return Status::OK;
1004}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001005
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001006Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001007 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001008 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
1009 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
1010 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001011
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001012 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001013 if (err == BCM_ERR_OK) {
1014 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001015 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001016 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1017 CreateDefaultSched(intf_id, upstream);
1018 CreateDefaultQueue(intf_id, upstream);
1019 return Status::OK;
1020 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1021 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
1022 return Status::OK;
1023 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001024 }
1025
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001026 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
1027 if (set_state) {
1028 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1029 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1030 } else {
1031 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1032 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1033 }
1034 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
1035 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001036 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err = %s\n",
1037 (set_state)?"enable":"disable", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001038 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
1039 }
1040 else {
1041 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
1042 if (set_state) {
1043 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1044 CreateDefaultSched(intf_id, upstream);
1045 CreateDefaultQueue(intf_id, upstream);
1046 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001047 }
1048
1049 return Status::OK;
1050}
1051
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001052Status DisablePonIf_(uint32_t intf_id) {
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001053 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001054 bcmolt_pon_interface_cfg interface_obj;
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001055 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1056 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001057
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001058 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
1059 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1060 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_DISABLE);
1061
1062 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1063 if (err != BCM_ERR_OK) {
1064 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable discovery of onu, PON interface %d, err %d\n", intf_id, err);
1065 return bcm_to_grpc_err(err, "Failed to disable discovery of onu");
1066 }
1067
1068 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1069 operation, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1070
1071 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1072 if (err != BCM_ERR_OK) {
1073 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n , err %d\n", intf_id, err);
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001074 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001075 }
1076
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001077 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled PON interface: %d\n", intf_id);
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001078 return Status::OK;
1079}
1080
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001081Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
kesavandc1f2db92020-08-31 15:32:06 +05301082 const char *vendor_id, const char *vendor_specific, uint32_t pir, bool omcc_encryption_mode) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001083 bcmos_errno err = BCM_ERR_OK;
1084 bcmolt_onu_cfg onu_cfg;
1085 bcmolt_onu_key onu_key;
1086 bcmolt_serial_number serial_number; /**< ONU serial number */
1087 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001088
Girish Gowdra24297032020-03-23 12:32:37 -07001089 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1090 bcmolt_onu_state onu_state;
1091
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001092 onu_key.onu_id = onu_id;
1093 onu_key.pon_ni = intf_id;
1094 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1095 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Girish Gowdra24297032020-03-23 12:32:37 -07001096#ifdef TEST_MODE
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001097 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1098 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1099 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1100 // of onu_cfg is passed. This is one-of case where we need to add test specific
1101 // code in production code.
1102 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Girish Gowdra24297032020-03-23 12:32:37 -07001103#else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001104 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Girish Gowdra24297032020-03-23 12:32:37 -07001105#endif
1106 OPENOLT_LOG(INFO, openolt_log_id, "Activate ONU : old state = %d, current state = %d\n",
1107 onu_cfg.data.onu_old_state, onu_cfg.data.onu_state);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001108 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001109 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) {
1110 OPENOLT_LOG(INFO, openolt_log_id, "ONU is already in ACTIVE state, \
1111not processing this request for pon_intf=%d onu_id=%d\n", intf_id, onu_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001112 return Status::OK;
Girish Gowdra24297032020-03-23 12:32:37 -07001113 } else if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_NOT_CONFIGURED &&
1114 onu_cfg.data.onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1115 // We need the ONU to be in NOT_CONFIGURED or INACTIVE state to further process the request
1116 OPENOLT_LOG(ERROR, openolt_log_id, "ONU in an invalid state to process the request, \
1117state=%d pon_intf=%d onu_id=%d\n", onu_cfg.data.onu_state, intf_id, onu_id);
1118 return bcm_to_grpc_err(err, "Failed to activate ONU, invalid ONU state");
1119 }
1120 } else {
1121 // This should never happen. BAL GET should succeed for non-existant ONUs too. The state of such ONUs will be NOT_CONFIGURED
1122 OPENOLT_LOG(ERROR, openolt_log_id, "ONU state query failed pon_intf=%d onu_id=%d\n", intf_id, onu_id);
1123 return bcm_to_grpc_err(err, "onu get failed");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001124 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001125
Girish Gowdra24297032020-03-23 12:32:37 -07001126 // If the ONU is not configured at all we need to first configure it
1127 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_NOT_CONFIGURED) {
1128 OPENOLT_LOG(INFO, openolt_log_id, "Configuring ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001129vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Girish Gowdra24297032020-03-23 12:32:37 -07001130 vendor_specific_to_str(vendor_specific).c_str(), pir);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001131
Girish Gowdra24297032020-03-23 12:32:37 -07001132 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1133 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1134 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1135 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1136 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1137 /*set burst and data profiles to fec disabled*/
1138 if (board_technology == "XGS-PON") {
1139 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1140 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1141 } else if (board_technology == "GPON") {
1142 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1143 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1144 }
1145 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1146 if (err != BCM_ERR_OK) {
1147 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to configure ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
1148 return bcm_to_grpc_err(err, "Failed to configure ONU");
1149 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001150 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001151
kesavandc1f2db92020-08-31 15:32:06 +05301152 if (omcc_encryption_mode == true) {
1153 // set the encryption mode for omci port id
1154 bcmolt_itupon_gem_cfg gem_cfg;
1155 bcmolt_itupon_gem_key key = {};
1156 bcmolt_gem_port_configuration configuration = {};
1157 key.pon_ni = intf_id;
1158 key.gem_port_id = onu_id;
1159 bcmolt_control_state encryption_mode;
1160 encryption_mode = BCMOLT_CONTROL_STATE_ENABLE;
1161 BCMOLT_CFG_INIT(&gem_cfg, itupon_gem, key);
1162 BCMOLT_FIELD_SET(&gem_cfg.data, itupon_gem_cfg_data, encryption_mode, encryption_mode);
1163 err = bcmolt_cfg_set(dev_id, &gem_cfg.hdr);
1164 if(err != BCM_ERR_OK) {
1165 OPENOLT_LOG(ERROR, openolt_log_id, "failed to confiure omci gem_port encryption mode = %d\n", onu_id);
1166 return bcm_to_grpc_err(err, "Access_Control set ITU PON OMCI Gem port failed");
1167 }
1168 }
Girish Gowdra24297032020-03-23 12:32:37 -07001169 // Now that the ONU is configured, move the ONU to ACTIVE state
1170 memset(&onu_cfg, 0, sizeof(bcmolt_onu_cfg));
1171 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1172 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1173 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
1174 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
1175 onu_state, BCMOLT_ONU_OPERATION_ACTIVE);
1176 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001177 if (err != BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001178 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 +00001179 return bcm_to_grpc_err(err, "Failed to activate ONU");
1180 }
Girish Gowdra24297032020-03-23 12:32:37 -07001181 // ONU will eventually get activated after we have submitted the operation request. The adapter will receive an asynchronous
1182 // ONU_ACTIVATION_COMPLETED_INDICATION
1183
1184 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 +00001185
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001186 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001187}
1188
Jonathan Davis70c21812018-07-19 15:32:10 -04001189Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1190 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001191 bcmos_errno err = BCM_ERR_OK;
1192 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1193 bcmolt_onu_cfg onu_cfg;
1194 bcmolt_onu_key onu_key; /**< Object key. */
1195 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001196
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001197 onu_key.onu_id = onu_id;
1198 onu_key.pon_ni = intf_id;
1199 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1200 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001201 #ifdef TEST_MODE
1202 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1203 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1204 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1205 // of onu_cfg is passed. This is one-of case where we need to add test specific
1206 // code in production code.
1207 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001208 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001209 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001210 #endif
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301211 onu_state = onu_cfg.data.onu_state;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001212 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001213 switch (onu_state) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001214 case BCMOLT_ONU_STATE_ACTIVE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001215 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001216 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001217 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1218 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1219 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001220 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 +00001221 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1222 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301223 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 +00001224 break;
1225 }
Jonathan Davis70c21812018-07-19 15:32:10 -04001226 }
1227
1228 return Status::OK;
1229}
1230
1231Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001232 const char *vendor_id, const char *vendor_specific) {
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301233 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301234 bcmolt_onu_state onu_state;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001235
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001236 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 -05001237 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1238
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001239 // Need to deactivate before removing it (BAL rules)
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001240 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301241
1242 err = get_onu_status((bcmolt_interface)intf_id, onu_id, &onu_state);
1243 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001244 if (onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1245 OPENOLT_LOG(INFO, openolt_log_id, "waiting for onu deactivate complete response: intf_id=%d, onu_id=%d\n",
1246 intf_id, onu_id);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301247 err = wait_for_onu_deactivate_complete(intf_id, onu_id);
1248 if (err) {
1249 OPENOLT_LOG(ERROR, openolt_log_id, "failed to delete onu intf_id %d, onu_id %d\n",
1250 intf_id, onu_id);
1251 return bcm_to_grpc_err(err, "Failed to delete ONU");
1252 }
1253 }
Girish Gowdra24297032020-03-23 12:32:37 -07001254 else {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301255 OPENOLT_LOG(INFO, openolt_log_id, "Onu is Inactive, onu_id: %d, not waiting for onu deactivate complete response\n",
1256 intf_id);
1257 }
1258 }
1259 else {
1260 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch Onu status, onu_id = %d, intf_id = %d, err = %s\n",
1261 onu_id, intf_id, bcmos_strerror(err));
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301262 return bcm_to_grpc_err(err, "Failed to delete ONU");
1263 }
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001264
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001265 bcmolt_onu_cfg cfg_obj;
1266 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001267
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001268 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 -04001269 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001270
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001271 key.onu_id = onu_id;
1272 key.pon_ni = intf_id;
1273 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001274
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301275 err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001276 if (err != BCM_ERR_OK)
1277 {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001278 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 -04001279 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1280 }
1281
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301282 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 +00001283 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001284}
1285
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001286#define MAX_CHAR_LENGTH 20
1287#define MAX_OMCI_MSG_LENGTH 44
1288Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001289 bcmolt_bin_str buf = {};
1290 bcmolt_onu_cpu_packets omci_cpu_packets;
1291 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001292
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001293 key.pon_ni = intf_id;
1294 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001295
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001296 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1297 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1298 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001299
1300 // ???
1301 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1302 buf.len = MAX_OMCI_MSG_LENGTH;
1303 } else {
1304 buf.len = pkt.size()/2;
1305 }
1306
1307 /* Send the OMCI packet using the BAL remote proxy API */
1308 uint16_t idx1 = 0;
1309 uint16_t idx2 = 0;
1310 uint8_t arraySend[buf.len];
1311 char str1[MAX_CHAR_LENGTH];
1312 char str2[MAX_CHAR_LENGTH];
1313 memset(&arraySend, 0, buf.len);
1314
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001315 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1316 sprintf(str1,"%c", pkt[idx1]);
1317 sprintf(str2,"%c", pkt[++idx1]);
1318 strcat(str1,str2);
1319 arraySend[idx2] = strtol(str1, NULL, 16);
1320 }
1321
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001322 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1323 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001324
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001325 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1326 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1327 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001328
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001329 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001330 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001331 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 +00001332 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001333 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001334 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 -05001335 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001336 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001337 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001338
1339 return Status::OK;
1340}
1341
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001342Status 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 +00001343 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1344 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1345 bcmolt_bin_str buf = {};
1346 bcmolt_gem_port_id gem_port_id_array[1];
1347 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001348
Craig Lutgen967a1d02018-11-27 10:41:51 -06001349 if (port_no > 0) {
1350 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001351 if (gemport_id == 0) {
1352 bcmos_fastlock_lock(&data_lock);
1353 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1354 // Pick any flow that is mapped with the same port_no.
1355 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1356 if (it != port_to_flows.end() && !it->second.empty()) {
1357 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1358 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1359 if (fit != flowid_to_gemport.end()) {
1360 found = true;
1361 gemport_id = fit->second;
1362 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001363 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001364 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001365
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001366 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001367 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 -08001368 onu_id, port_no, intf_id);
1369 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1370 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001371 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 -08001372 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001373 }
1374
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001375 gem_port_id_array[0] = gemport_id;
1376 gem_port_list.len = 1;
1377 gem_port_list.arr = gem_port_id_array;
1378 buf.len = pkt.size();
1379 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1380 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1381
1382 /* init the API struct */
1383 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1384 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1385 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1386 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1387 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1388
1389 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1390 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1391
1392 /* call API */
1393 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001394 }
1395 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001396 //TODO: Port No is 0, it is coming sender requirement.
1397 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1398 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001399 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001400 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001401
1402 return Status::OK;
1403}
1404
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001405Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001406 bcmolt_flow_key key = {}; /* declare key */
1407 bcmolt_bin_str buffer = {};
1408 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001409
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001410 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
Girish Gowdra252f4972020-09-07 21:24:01 -07001411 bcmolt_flow_id flow_id = INVALID_FLOW_ID;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001412
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001413 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1414 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1415 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1416 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1417 key.flow_id = flow_id;
1418 else {
Jason Huang09b73ea2020-01-08 17:52:05 +08001419 if (flow_id_counters) {
1420 std::map<flow_pair, int>::iterator it;
1421 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1422 int flow_index = it->first.first;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001423 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1424 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1425 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1426 key.flow_id = flow_index;
1427 break;
1428 }
1429 }
1430 }
1431 else {
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001432 OPENOLT_LOG(ERROR, openolt_log_id, "no flow id found for uplink packetout\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001433 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1434 }
1435 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001436
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001437 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001438
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001439 /* Initialize the API struct. */
1440 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001441
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001442 buffer.len = pkt.size();
1443 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1444 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1445 if (buffer.arr == NULL) {
1446 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1447 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1448 }
1449 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1450
1451 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1452 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001453 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 -05001454 return bcm_to_grpc_err(BCM_ERR_SYSCALL_ERR, "Error sending packets via nni port");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001455 } else {
1456 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1457 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001458
1459 return Status::OK;
1460}
Girish Gowdra252f4972020-09-07 21:24:01 -07001461
1462Status FlowAddWrapper_(const ::openolt::Flow* request) {
1463
1464 int32_t access_intf_id = request->access_intf_id();
1465 int32_t onu_id = request->onu_id();
1466 int32_t uni_id = request->uni_id();
1467 uint32_t port_no = request->port_no();
1468 uint64_t voltha_flow_id = request->flow_id();
1469 uint64_t symmetric_voltha_flow_id = request->symmetric_flow_id();
1470 const std::string flow_type = request->flow_type();
1471 int32_t alloc_id = request->alloc_id();
1472 int32_t network_intf_id = request->network_intf_id();
1473 int32_t gemport_id = request->gemport_id();
1474 const ::openolt::Classifier& classifier = request->classifier();
1475 const ::openolt::Action& action = request->action();
1476 int32_t priority = request->priority();
1477 uint64_t cookie = request->cookie();
1478 int32_t group_id = request->group_id();
1479 uint32_t tech_profile_id = request->tech_profile_id();
1480 bool replicate_flow = request->replicate_flow();
1481 const google::protobuf::Map<unsigned int, unsigned int> &pbit_to_gemport = request->pbit_to_gemport();
1482 uint16_t flow_id;
1483
1484 // The intf_id variable defaults to access(PON) interface ID.
1485 // For trap-from-nni flow where access interface ID is not valid , change it to NNI interface ID
1486 // This intf_id identifies the pool from which we get the flow_id
1487 uint32_t intf_id = access_intf_id;
1488 if (onu_id < 1) {
1489 onu_id = 1;
1490 }
1491 if (access_intf_id < 0) {
1492 intf_id = network_intf_id;
1493 }
1494
1495 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)
1496 // This is the case of voltha_flow_id (not symmetric_voltha_flow_id)
1497 if (is_voltha_flow_installed(voltha_flow_id)) {
1498 OPENOLT_LOG(INFO, openolt_log_id, "voltha_flow_id=%lu, already installed\n", voltha_flow_id);
1499 return ::Status(grpc::StatusCode::ALREADY_EXISTS, "voltha-flow-already-installed");
1500 }
1501
Girish Gowdra252f4972020-09-07 21:24:01 -07001502 // This is the case of symmetric_voltha_flow_id
1503 // If symmetric_voltha_flow_id is available and valid in the Flow message,
1504 // check if it is installed, and use the corresponding device_flow_id
1505 if (symmetric_voltha_flow_id > 0 && is_voltha_flow_installed(symmetric_voltha_flow_id)) { // symmetric flow found
1506 OPENOLT_LOG(INFO, openolt_log_id, "symmetric flow and the symmetric flow is installed\n");
1507 const device_flow_params *dev_fl_symm_params;
1508 dev_fl_symm_params = get_device_flow_params(symmetric_voltha_flow_id);
1509 if (dev_fl_symm_params == NULL) {
1510 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)
1511 return ::Status(grpc::StatusCode::INTERNAL, "symmetric-flow-details-not-found");
1512 }
1513
1514 if (!replicate_flow) { // No flow replication
1515 flow_id = dev_fl_symm_params[0].flow_id;
1516 gemport_id = dev_fl_symm_params[0].gemport_id; // overwrite the gemport with symmetric flow gemport
1517 // Should be same as what is coming in this request.
1518 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1519 cl.set_o_pbits(dev_fl_symm_params[0].pbit);
1520 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1521 flow_type, alloc_id, network_intf_id, gemport_id, cl,
1522 action, priority, cookie, group_id, tech_profile_id);
1523 if (st.error_code() == grpc::StatusCode::OK) {
1524 device_flow dev_fl;
1525 dev_fl.is_flow_replicated = false;
1526 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1527 dev_fl.voltha_flow_id = voltha_flow_id;
1528 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params));
1529 // update voltha flow to cache
1530 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1531 }
1532 return st;
1533 } else { // Flow to be replicated
1534 OPENOLT_LOG(INFO, openolt_log_id,"symmetric flow and replication is needed\n");
1535 for (uint8_t i=0; i<NUMBER_OF_REPLICATED_FLOWS; i++) {
1536 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1537 flow_id = dev_fl_symm_params[i].flow_id;
1538 gemport_id = dev_fl_symm_params[i].gemport_id;
1539 cl.set_o_pbits(dev_fl_symm_params[i].pbit);
1540 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1541 flow_type, alloc_id, network_intf_id, gemport_id, classifier,
1542 action, priority, cookie, group_id, tech_profile_id);
1543 if (st.error_code() != grpc::StatusCode::OK && st.error_code() != grpc::StatusCode::ALREADY_EXISTS) {
1544 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);
1545 // On failure remove any successfully replicated flows installed so far for the voltha_flow_id
1546 if (i > 0) {
1547 for (int8_t j = i-1; j >= 0; j--) {
1548 flow_id = dev_fl_symm_params[j].flow_id;
1549 FlowRemove_(flow_id, flow_type);
1550 }
1551 }
1552 return st;
1553 }
1554 }
1555 device_flow dev_fl;
1556 dev_fl.is_flow_replicated = true;
1557 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1558 dev_fl.voltha_flow_id = voltha_flow_id;
1559 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params)*NUMBER_OF_REPLICATED_FLOWS);
1560 // update voltha flow to cache
1561 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1562 }
1563 } else { // No symmetric flow found
1564 if (!replicate_flow) { // No flow replication
1565 OPENOLT_LOG(INFO, openolt_log_id, "not a symmetric flow and replication is not needed\n");
1566 flow_id = get_flow_id();
1567 if (flow_id == INVALID_FLOW_ID) {
1568 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocated flow id for voltha-flow-id=%lu\n", voltha_flow_id);
1569 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1570 }
1571 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1572 flow_type, alloc_id, network_intf_id, gemport_id, classifier,
1573 action, priority, cookie, group_id, tech_profile_id);
1574 if (st.error_code() == grpc::StatusCode::OK) {
1575 device_flow dev_fl;
1576 dev_fl.is_flow_replicated = false;
1577 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // Invalid
1578 dev_fl.voltha_flow_id = voltha_flow_id;
1579 dev_fl.params[0].flow_id = flow_id;
1580 dev_fl.params[0].gemport_id = gemport_id;
1581 dev_fl.params[0].pbit = classifier.o_pbits();
1582 // update voltha flow to cache
1583 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1584 } else {
1585 // Free the flow id on failure
1586 free_flow_id(flow_id);
1587 }
1588 return st;
1589 } else { // Flow to be replicated
1590 OPENOLT_LOG(INFO, openolt_log_id,"not a symmetric flow and replication is needed\n");
1591 if (pbit_to_gemport.size() != NUMBER_OF_PBITS) {
1592 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pbit-to-gemport map size=%lu", pbit_to_gemport.size())
1593 return ::Status(grpc::StatusCode::OUT_OF_RANGE, "pbit-to-gemport-map-len-invalid-for-flow-replication");
1594 }
1595 uint16_t flow_ids[NUMBER_OF_REPLICATED_FLOWS];
1596 device_flow dev_fl;
1597 if (get_flow_ids(NUMBER_OF_REPLICATED_FLOWS, flow_ids)) {
1598 uint8_t cnt = 0;
1599 dev_fl.is_flow_replicated = true;
1600 dev_fl.voltha_flow_id = voltha_flow_id;
1601 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // invalid
1602 for (google::protobuf::Map<unsigned int, unsigned int>::const_iterator it=pbit_to_gemport.begin(); it!=pbit_to_gemport.end(); it++) {
1603 dev_fl.params[cnt].flow_id = flow_ids[cnt];
1604 dev_fl.params[cnt].pbit = it->first;
1605 dev_fl.params[cnt].gemport_id = it->second;
1606
1607 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1608 flow_id = dev_fl.params[cnt].flow_id;
1609 gemport_id = dev_fl.params[cnt].gemport_id;
1610 cl.set_o_pbits(dev_fl.params[cnt].pbit);
1611 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1612 flow_type, alloc_id, network_intf_id, gemport_id, cl,
1613 action, priority, cookie, group_id, tech_profile_id);
1614 if (st.error_code() != grpc::StatusCode::OK) {
1615 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);
1616 // Remove any successfully replicated flows installed so far for the voltha_flow_id
1617 if (cnt > 0) {
1618 for (int8_t j = cnt-1; j >= 0; j--) {
1619 flow_id = dev_fl.params[j].flow_id;
1620 FlowRemove_(flow_id, flow_type);
1621 }
1622 }
1623 // Free up all the flow IDs on failure
1624 free_flow_ids(NUMBER_OF_REPLICATED_FLOWS, flow_ids);
1625 return st;
1626 }
1627 cnt++;
1628 }
1629 // On successful flow replication update voltha-flow-id to device-flow map to cache
1630 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1631 } else {
1632 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocate flow ids for replication voltha-flow-id=%lu\n", voltha_flow_id);
1633 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1634 }
1635 }
1636 }
1637
1638 return Status::OK;
1639}
1640
1641
Craig Lutgen967a1d02018-11-27 10:41:51 -06001642Status 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 +00001643 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001644 int32_t alloc_id, int32_t network_intf_id,
1645 int32_t gemport_id, const ::openolt::Classifier& classifier,
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001646 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00001647 int32_t group_id, uint32_t tech_profile_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001648 bcmolt_flow_cfg cfg;
1649 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001650 int32_t o_vid = -1;
1651 bool single_tag = false;
1652 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001653 bcmolt_classifier c_val = { };
1654 bcmolt_action a_val = { };
1655 bcmolt_tm_queue_ref tm_val = { };
1656 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05001657 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001658
Jason Huang09b73ea2020-01-08 17:52:05 +08001659 OPENOLT_LOG(INFO, openolt_log_id, "flow add received for flow_id=%u, flow_type=%s\n", flow_id, flow_type.c_str());
1660
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001661 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001662 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001663 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001664 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001665 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001666 } else if (flow_type.compare(multicast) == 0) {
1667 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001668 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001669 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001670 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001671 }
1672
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001673 BCMOLT_CFG_INIT(&cfg, flow, key);
1674 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001675
Jason Huang09b73ea2020-01-08 17:52:05 +08001676 if (action.cmd().trap_to_host()) {
Girish Gowdra1935e6a2020-10-31 21:48:22 -07001677 Status resp = handle_acl_rule_install(onu_id, flow_id, gemport_id, flow_type, access_intf_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001678 network_intf_id, classifier);
Jason Huang09b73ea2020-01-08 17:52:05 +08001679 return resp;
1680 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001681
1682 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1683
1684 if (access_intf_id >= 0 && network_intf_id >= 0) {
1685 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1686 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1687 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08001688 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1689 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001690 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1691 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1692 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1693 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1694 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001695 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001696 } else {
1697 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
1698 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001699 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001700
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001701 if (onu_id >= 0) {
1702 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
1703 }
1704 if (gemport_id >= 0) {
1705 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
1706 }
1707 if (gemport_id >= 0 && port_no != 0) {
1708 bcmos_fastlock_lock(&data_lock);
1709 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
1710 port_to_flows[port_no].insert(key.flow_id);
1711 flowid_to_gemport[key.flow_id] = gemport_id;
1712 }
1713 else
1714 {
1715 flowid_to_port[key.flow_id] = port_no;
1716 }
1717 bcmos_fastlock_unlock(&data_lock, 0);
1718 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001719
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001720 if (priority_value >= 0) {
1721 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
1722 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301723
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001724 } else { // MULTICAST FLOW
1725 if (group_id >= 0) {
1726 BCMOLT_MSG_FIELD_SET(&cfg, group_id, group_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001727 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001728 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1729 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001730 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001731
1732 {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001733 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001734 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001735 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
1736 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001737 }
1738
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001739 if (classifier.dst_mac().size() > 0) {
1740 bcmos_mac_address d_mac = {};
1741 bcmos_mac_address_init(&d_mac);
1742 memcpy(d_mac.u8, classifier.dst_mac().data(), sizeof(d_mac.u8));
1743 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_mac %02x:%02x:%02x:%02x:%02x:%02x\n", d_mac.u8[0],
1744 d_mac.u8[1], d_mac.u8[2], d_mac.u8[3], d_mac.u8[4], d_mac.u8[5]);
1745 BCMOLT_FIELD_SET(&c_val, classifier, dst_mac, d_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001746 }
1747
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001748 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001749 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001750 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001751 }
1752 */
1753
1754 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001755 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
1756 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001757 }
1758
1759 /*
1760 if (classifier.dst_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001761 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_ip, classifier.dst_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001762 }
1763
1764 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001765 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001766 }
1767 */
1768
1769 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001770 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
1771 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001772 }
1773
1774 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001775 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
1776 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001777 }
1778
1779 if (!classifier.pkt_tag_type().empty()) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001780 if (classifier.o_vid()) {
1781 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
1782 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
1783 }
1784
1785 if (classifier.i_vid()) {
1786 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
1787 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
1788 }
1789
1790 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
1791 if (classifier.pkt_tag_type().compare("untagged") == 0) {
1792 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
1793 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
1794 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
1795 single_tag = true;
1796
1797 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301798 // OpenOlt adapter will send 0xFF in case of no pbit classification
1799 // If it is any other value (0 to 7), it is for outer pbit classification.
1800 // OpenFlow protocol does not provide inner pbit classification (in case of double tagged packets),
1801 // and VOLTHA has not used any workaround to solve this problem (for ex: use metadata field).
1802 // Also there exists no use case for i-pbit classification, so we can safely ignore this for now.
1803 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001804 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301805 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001806 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
1807 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001808
Jason Huang09b73ea2020-01-08 17:52:05 +08001809 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301810 // Same comments as in case of "single_tag" packets.
1811 // 0xFF means no pbit classification, otherwise a valid PCP (0 to 7).
1812 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001813 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301814 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001815 }
1816 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001817 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001818 }
1819
Jason Huang09b73ea2020-01-08 17:52:05 +08001820 const ::openolt::ActionCmd& cmd = action.cmd();
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001821
Jason Huang09b73ea2020-01-08 17:52:05 +08001822 if (cmd.add_outer_tag()) {
1823 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
1824 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001825 }
1826
Jason Huang09b73ea2020-01-08 17:52:05 +08001827 if (cmd.remove_outer_tag()) {
1828 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
1829 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
1830 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301831
Jason Huang09b73ea2020-01-08 17:52:05 +08001832 if (action.o_vid()) {
1833 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
1834 o_vid = action.o_vid();
1835 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
1836 }
1837
1838 if (action.o_pbits()) {
1839 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
1840 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
1841 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301842
Jason Huang09b73ea2020-01-08 17:52:05 +08001843 if (action.i_vid()) {
1844 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
1845 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
1846 }
1847
1848 if (action.i_pbits()) {
1849 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
1850 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
1851 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301852
Jason Huang09b73ea2020-01-08 17:52:05 +08001853 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
1854
Shad Ansari39739bc2018-09-13 21:38:37 +00001855 if ((access_intf_id >= 0) && (onu_id >= 0)) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001856 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
1857 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00001858 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 +00001859
Jason Huang09b73ea2020-01-08 17:52:05 +08001860 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1861 // Queue 0 on DS subscriber scheduler
1862 tm_val.queue_id = 0;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001863
Jason Huang09b73ea2020-01-08 17:52:05 +08001864 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1865 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1866 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001867
Jason Huang09b73ea2020-01-08 17:52:05 +08001868 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1869 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1870 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001871
Jason Huang09b73ea2020-01-08 17:52:05 +08001872 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1873 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
1874 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 +00001875
Jason Huang09b73ea2020-01-08 17:52:05 +08001876 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1877 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1878 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1879 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 +00001880
Jason Huang09b73ea2020-01-08 17:52:05 +08001881 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
1882 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1883 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1884 }
1885 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
1886 // NNI Scheduler ID
1887 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1888 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1889 // Queue 0 on NNI scheduler
1890 tm_val.queue_id = 0;
1891 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1892 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1893 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001894
Jason Huang09b73ea2020-01-08 17:52:05 +08001895 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 +00001896 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1897 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1898
Jason Huang09b73ea2020-01-08 17:52:05 +08001899 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1900 /* Fetch TM QMP ID mapped to US NNI scheduler */
1901 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
1902 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1903 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1904 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1905 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 +00001906
Jason Huang09b73ea2020-01-08 17:52:05 +08001907 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 +00001908 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1909 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001910 }
Shad Ansari39739bc2018-09-13 21:38:37 +00001911 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301912 } else {
1913 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1914 tm_val.queue_id = 0;
1915
1916 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
1917 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1918 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
1919
1920 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1921 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
1922 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00001923 }
1924
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001925 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001926
Girish Gowdra252f4972020-09-07 21:24:01 -07001927#ifndef SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001928 // BAL 3.1 supports statistics only for unicast flows.
1929 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1930 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
1931 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001932#endif // SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001933
Girish Gowdra252f4972020-09-07 21:24:01 -07001934#ifndef SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001935#ifdef FLOW_CHECKER
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001936 //Flow Checker, To avoid duplicate flow.
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001937 if (flow_id_counters != 0) {
1938 bool b_duplicate_flow = false;
Jason Huang09b73ea2020-01-08 17:52:05 +08001939 std::map<flow_pair, int>::iterator it;
1940
1941 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1942 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(it->first.first, it->first.second, ONU_ID)) && \
1943 (key.flow_type == it->first.second) && \
1944 (cfg.data.svc_port_id == get_flow_status(it->first.first, it->first.second, SVC_PORT_ID)) && \
1945 (cfg.data.priority == get_flow_status(it->first.first, it->first.second, PRIORITY)) && \
1946 (cfg.data.cookie == get_flow_status(it->first.first, it->first.second, COOKIE)) && \
1947 (cfg.data.ingress_intf.intf_type == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_TYPE)) && \
1948 (cfg.data.ingress_intf.intf_id == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_ID)) && \
1949 (cfg.data.egress_intf.intf_type == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_TYPE)) && \
1950 (cfg.data.egress_intf.intf_id == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_ID)) && \
1951 (c_val.o_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_VID)) && \
1952 (c_val.o_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_PBITS)) && \
1953 (c_val.i_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_VID)) && \
1954 (c_val.i_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_PBITS)) && \
1955 (c_val.ether_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_ETHER_TYPE)) && \
1956 (c_val.ip_proto == get_flow_status(it->first.first, it->first.second, CLASSIFIER_IP_PROTO)) && \
1957 (c_val.src_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_SRC_PORT)) && \
1958 (c_val.dst_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_DST_PORT)) && \
1959 (c_val.pkt_tag_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_PKT_TAG_TYPE)) && \
1960 (cfg.data.egress_qos.type == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TYPE)) && \
1961 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_QUEUE_ID)) && \
1962 (cfg.data.egress_qos.tm_sched.id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TM_SCHED_ID)) && \
1963 (a_val.cmds_bitmask == get_flow_status(it->first.first, it->first.second, ACTION_CMDS_BITMASK)) && \
1964 (a_val.o_vid == get_flow_status(it->first.first, it->first.second, ACTION_O_VID)) && \
1965 (a_val.i_vid == get_flow_status(it->first.first, it->first.second, ACTION_I_VID)) && \
1966 (a_val.o_pbits == get_flow_status(it->first.first, it->first.second, ACTION_O_PBITS)) && \
1967 (a_val.i_pbits == get_flow_status(it->first.first, it->first.second, ACTION_I_PBITS)) && \
1968 (cfg.data.state == get_flow_status(it->first.first, it->first.second, STATE)) && \
1969 (cfg.data.group_id == get_flow_status(it->first.first, it->first.second, GROUP_ID));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001970#ifdef SHOW_FLOW_PARAM
1971 // Flow Parameter
1972 FLOW_PARAM_LOG();
1973#endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001974 if (b_duplicate_flow) {
1975 FLOW_LOG(WARNING, "Flow duplicate", 0);
1976 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
1977 }
1978 }
1979 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001980#endif // FLOW_CHECKER
1981#endif // SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001982
1983 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
1984 if (err) {
1985 FLOW_LOG(ERROR, "Flow add failed", err);
1986 return bcm_to_grpc_err(err, "flow add failed");
1987 } else {
1988 FLOW_LOG(INFO, "Flow add ok", err);
1989 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08001990 flow_map[std::pair<int, int>(key.flow_id,key.flow_type)] = flow_map.size();
1991 flow_id_counters = flow_map.size();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001992 bcmos_fastlock_unlock(&data_lock, 0);
Girish Gowdra252f4972020-09-07 21:24:01 -07001993
1994 }
1995 return Status::OK;
1996}
1997
1998Status FlowRemoveWrapper_(const ::openolt::Flow* request) {
1999 const std::string flow_type = request->flow_type();
2000 uint64_t voltha_flow_id = request->flow_id();
2001 Status st;
2002
2003 // If Voltha flow is not installed, return fail
2004 if (! is_voltha_flow_installed(voltha_flow_id)) {
2005 OPENOLT_LOG(ERROR, openolt_log_id, "voltha_flow_id=%lu not found\n", voltha_flow_id);
2006 return ::Status(grpc::StatusCode::NOT_FOUND, "voltha-flow-not-found");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002007 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04002008
Girish Gowdra252f4972020-09-07 21:24:01 -07002009 const device_flow *dev_fl = get_device_flow(voltha_flow_id);
2010 if (dev_fl == NULL) {
2011 OPENOLT_LOG(ERROR, openolt_log_id, "device flow for voltha_flow_id=%lu in the cache is NULL\n", voltha_flow_id);
2012 return ::Status(grpc::StatusCode::INTERNAL, "device-flow-null-in-cache");
2013 }
2014 if (dev_fl->is_flow_replicated) {
2015 // Note: Here we are ignoring FlowRemove failures
2016 for (int i=0; i<NUMBER_OF_REPLICATED_FLOWS; i++) {
2017 st = FlowRemove_(dev_fl->params[i].flow_id, flow_type);
2018 if (st.error_code() == grpc::StatusCode::OK) {
2019 free_flow_id(dev_fl->params[i].flow_id);
2020 }
2021 }
2022 } else {
2023 // Note: Here we are ignoring FlowRemove failures
2024 st = FlowRemove_(dev_fl->params[0].flow_id, flow_type);
2025 if (st.error_code() == grpc::StatusCode::OK) {
2026 free_flow_id(dev_fl->params[0].flow_id);
2027 }
2028 }
2029 // remove the flow from cache on voltha flow removal
2030 remove_voltha_flow_from_cache(voltha_flow_id);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002031 return Status::OK;
2032}
2033
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002034Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
2035
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002036 bcmolt_flow_cfg cfg;
2037 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002038
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002039 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002040 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002041 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002042 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002043 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002044 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002045 } else if(flow_type.compare(multicast) == 0) {
2046 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002047 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002048 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002049 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
2050 }
2051
Jason Huang09b73ea2020-01-08 17:52:05 +08002052 OPENOLT_LOG(INFO, openolt_log_id, "flow remove received for flow_id=%u, flow_type=%s\n",
2053 flow_id, flow_type.c_str());
2054
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002055 bcmos_fastlock_lock(&acl_packet_trap_handler_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002056 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
2057 int32_t gemport_id = -1;
2058 int32_t intf_id = -1;
2059 int16_t acl_id = -1;
2060 if (flow_to_acl_map.count(fl_id_fl_dir) > 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002061
2062 acl_id_intf_id ac_id_if_id = flow_to_acl_map[fl_id_fl_dir];
2063 acl_id = std::get<0>(ac_id_if_id);
2064 intf_id = std::get<1>(ac_id_if_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002065 // cleanup acl only if it is a valid acl. If not valid acl, it may be datapath flow.
2066 if (acl_id >= 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002067 Status resp = handle_acl_rule_cleanup(acl_id, intf_id, flow_type);
Jason Huang09b73ea2020-01-08 17:52:05 +08002068 if (resp.ok()) {
2069 OPENOLT_LOG(INFO, openolt_log_id, "acl removed ok for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2070 flow_to_acl_map.erase(fl_id_fl_dir);
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002071
2072 // 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
2073 if (trap_to_host_pkt_info_with_vlan_for_flow_id.count(flow_id) > 0) {
2074 trap_to_host_pkt_info_with_vlan pkt_info_with_vlan = trap_to_host_pkt_info_with_vlan_for_flow_id[flow_id];
2075 // Formulate the trap_to_host_pkt_info tuple key
2076 trap_to_host_pkt_info pkt_info(std::get<0>(pkt_info_with_vlan),
2077 std::get<1>(pkt_info_with_vlan),
2078 std::get<2>(pkt_info_with_vlan),
2079 std::get<3>(pkt_info_with_vlan));
2080 // Extract the value corresponding to trap_to_host_pkt_info key from trap_to_host_vlan_ids_for_trap_to_host_pkt_info
2081 // The value is a list of vlan_ids for the given trap_to_host_pkt_info key
2082 // Remove the vlan_id from the list that corresponded to the flow being removed.
2083 if (trap_to_host_vlan_ids_for_trap_to_host_pkt_info.count(pkt_info) > 0) {
2084 trap_to_host_vlan_ids_for_trap_to_host_pkt_info[pkt_info].remove(std::get<4>(pkt_info_with_vlan));
2085 } else {
2086 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",
2087 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));
2088 }
2089
2090 } else {
2091 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);
2092 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002093 } else {
2094 OPENOLT_LOG(ERROR, openolt_log_id, "acl remove error for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2095 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002096 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002097 return resp;
2098 }
2099 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002100 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002101
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002102 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002103 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002104 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002105 flowid_to_gemport.erase(key.flow_id);
2106 port_to_flows[port_no].erase(key.flow_id);
2107 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
2108 }
2109 else
2110 {
2111 flowid_to_port.erase(key.flow_id);
2112 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002113 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002114
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002115 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002116
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002117 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002118 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002119 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 -04002120 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
2121 }
2122
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002123 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002124 if (flow_id_counters != 0) {
2125 std::map<flow_pair, int>::iterator it;
2126 for(it = flow_map.begin(); it != flow_map.end(); it++) {
2127 if (it->first.first == flow_id && it->first.second == key.flow_type) {
2128 flow_id_counters -= 1;
2129 flow_map.erase(it);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002130 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002131 }
2132 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002133 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
2134
Jason Huang09b73ea2020-01-08 17:52:05 +08002135 flow_to_acl_map.erase(fl_id_fl_dir);
2136
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002137 bcmos_fastlock_unlock(&data_lock, 0);
2138
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002139 return Status::OK;
2140}
2141
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002142bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
2143 bcmos_errno err;
2144 bcmolt_tm_sched_cfg tm_sched_cfg;
2145 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2146 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
2147
Jason Huangbf45ffb2019-10-30 17:29:02 +08002148 //check TM scheduler has configured or not
2149 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2150 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002151 #ifdef TEST_MODE
2152 // It is impossible to mock the setting of tm_sched_cfg.data.state because
2153 // the actual bcmolt_cfg_get passes the address of tm_sched_cfg.hdr and we cannot
2154 // set the tm_sched_cfg.data.state. So a new stub function is created and address
2155 // of tm_sched_cfg is passed. This is one-of case where we need to add test specific
2156 // code in production code.
2157 err = bcmolt_cfg_get__tm_sched_stub(dev_id, &tm_sched_cfg);
2158 #else
Jason Huangbf45ffb2019-10-30 17:29:02 +08002159 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002160 #endif
Jason Huangbf45ffb2019-10-30 17:29:02 +08002161 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002162 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 +08002163 return err;
2164 }
2165 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
2166 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
2167 return BCM_ERR_OK;
2168 }
2169
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002170 // bcmbal_tm_sched_owner
2171 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2172
2173 /**< The output of the tm_sched object instance */
2174 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
2175
2176 if (direction.compare(upstream) == 0) {
2177 // In upstream it is NNI scheduler
2178 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
2179 } else if (direction.compare(downstream) == 0) {
2180 // In downstream it is PON scheduler
2181 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2182 }
2183
2184 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2185
2186 // bcmbal_tm_sched_type
2187 // set the deafult policy to strict priority
2188 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2189
2190 // num_priorities: Max number of strict priority scheduling elements
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002191 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, NUM_OF_PRIORITIES);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002192
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002193 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2194 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002195 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
2196 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002197 return err;
2198 }
2199
2200 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2201 direction.c_str(), tm_sched_key.id, intf_id);
2202 return BCM_ERR_OK;
2203}
2204
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002205bcmos_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 -07002206 uint32_t alloc_id, ::tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
2207 ::tech_profile::SchedulingPolicy sched_policy, ::tech_profile::TrafficShapingInfo tf_sh_info,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002208 uint32_t tech_profile_id) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002209
2210 bcmos_errno err;
2211
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002212 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002213 bcmolt_tm_sched_cfg tm_sched_cfg;
2214 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002215 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 -04002216
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002217 // bcmbal_tm_sched_owner
2218 // In downstream it is sub_term scheduler
2219 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002220
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002221 /**< The output of the tm_sched object instance */
2222 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002223
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002224 // bcmbal_tm_sched_parent
2225 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2226 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
2227 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 +00002228 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002229 be achieved using the' virtual' type of attachment.
2230 tm_sched_owner.u.sub_term.intf_id = intf_id;
2231 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2232 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002233
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002234 // bcmbal_tm_sched_type
2235 // set the deafult policy to strict priority
2236 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002237
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002238 // num_priorities: Max number of strict priority scheduling elements
2239 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002240
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002241 // bcmbal_tm_shaping
2242 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2243 uint32_t cir = tf_sh_info.cir();
2244 uint32_t pir = tf_sh_info.pir();
2245 uint32_t burst = tf_sh_info.pbs();
2246 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2247 cir, pir, burst);
2248 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2249 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2250 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2251 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2252 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2253 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002254 }
2255
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002256 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002257 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002258 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002259intf_id %d, onu_id %d, uni_id %d, port_no %u, err = %s\n", tm_sched_key.id, intf_id, onu_id, uni_id, \
2260port_no, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002261 return err;
2262 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002263 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2264uni_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 -08002265
2266 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002267 bcmolt_itupon_alloc_cfg cfg;
2268 bcmolt_itupon_alloc_key key = { };
2269 key.pon_ni = intf_id;
2270 key.alloc_id = alloc_id;
2271 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
Burak Gurdag03919c72020-02-04 22:46:57 +00002272 int pir_bw = tf_sh_info.pir()*125; // conversion from kbps to bytes/sec
2273 int cir_bw = tf_sh_info.cir()*125; // conversion from kbps to bytes/sec
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002274 //offset to match bandwidth granularity
2275 int offset_pir_bw = pir_bw%bw_granularity;
2276 int offset_cir_bw = cir_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002277
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002278 pir_bw = pir_bw - offset_pir_bw;
2279 cir_bw = cir_bw - offset_cir_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002280
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002281 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002282
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002283 switch (additional_bw) {
2284 case 2: //AdditionalBW_BestEffort
2285 if (pir_bw == 0) {
2286 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2287%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002288 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002289 } else if (pir_bw < cir_bw) {
2290 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2291bandwidth (%d)\n", pir_bw, cir_bw);
2292 return BCM_ERR_PARM;
2293 } else if (pir_bw == cir_bw) {
2294 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2295bandwidth for additional bandwidth eligibility of type best_effort\n");
2296 return BCM_ERR_PARM;
2297 }
2298 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2299 break;
2300 case 1: //AdditionalBW_NA
2301 if (pir_bw == 0) {
2302 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2303%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2304 return BCM_ERR_PARM;
2305 } else if (cir_bw == 0) {
2306 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2307additional bandwidth eligibility of type Non-Assured (NA)\n");
2308 return BCM_ERR_PARM;
2309 } else if (pir_bw < cir_bw) {
2310 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2311bandwidth (%d)\n", pir_bw, cir_bw);
2312 return BCM_ERR_PARM;
2313 } else if (pir_bw == cir_bw) {
2314 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2315bandwidth for additional bandwidth eligibility of type non_assured\n");
2316 return BCM_ERR_PARM;
2317 }
2318 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2319 break;
2320 case 0: //AdditionalBW_None
2321 if (pir_bw == 0) {
2322 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
232316000 bytes/sec\n");
2324 return BCM_ERR_PARM;
2325 } else if (cir_bw == 0) {
2326 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2327for additional bandwidth eligibility of type None\n");
2328 return BCM_ERR_PARM;
2329 } else if (pir_bw > cir_bw) {
2330 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2331for additional bandwidth eligibility of type None\n");
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002332 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002333bandwidth in None eligibility\n", pir_bw);
2334 cir_bw = pir_bw;
2335 } else if (pir_bw < cir_bw) {
2336 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2337bandwidth (%d)\n", pir_bw, cir_bw);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002338 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002339bandwidth in None eligibility\n", pir_bw);
2340 cir_bw = pir_bw;
2341 }
2342 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2343 break;
2344 default:
2345 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002346 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002347 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2348 in a fine granularity. */
2349 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
2350 /* Fixed Bandwidth with no critical requirement of shaping */
2351 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, 0);
2352 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
2353 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, cir_bw);
2354 /* Maximum allocated bandwidth allowed for this alloc ID */
2355 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
2356 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002357 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002358 for skipped allocations during quiet window */
2359 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2360 /**< Allocation Profile index for CBR non-RT Bandwidth */
2361 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2362 /**< Allocation Profile index for CBR RT Bandwidth */
2363 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2364 /**< Alloc ID Weight used in case of Extended DBA mode */
2365 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2366 /**< Alloc ID Priority used in case of Extended DBA mode */
2367 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2368 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002369
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002370 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002371 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002372 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002373port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002374 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002375 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002376#ifndef SCALE_AND_PERF
Girish Gowdra96461052019-11-22 20:13:59 +05302377 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
2378 if (err) {
2379 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2380port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
2381 return err;
2382 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002383#endif
Girish Gowdra96461052019-11-22 20:13:59 +05302384
2385 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
2386port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
2387
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002388 }
2389
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002390 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002391}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002392
Girish Gowdra252f4972020-09-07 21:24:01 -07002393Status CreateTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002394 uint32_t intf_id = traffic_scheds->intf_id();
2395 uint32_t onu_id = traffic_scheds->onu_id();
2396 uint32_t uni_id = traffic_scheds->uni_id();
2397 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002398 std::string direction;
2399 unsigned int alloc_id;
Girish Gowdra252f4972020-09-07 21:24:01 -07002400 ::tech_profile::SchedulerConfig sched_config;
2401 ::tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002402 uint32_t priority;
2403 uint32_t weight;
Girish Gowdra252f4972020-09-07 21:24:01 -07002404 ::tech_profile::SchedulingPolicy sched_policy;
2405 ::tech_profile::TrafficShapingInfo traffic_shaping_info;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002406 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002407 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002408
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002409 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002410 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002411
2412 direction = GetDirection(traffic_sched.direction());
2413 if (direction.compare("direction-not-supported") == 0)
2414 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2415
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002416 alloc_id = traffic_sched.alloc_id();
2417 sched_config = traffic_sched.scheduler();
2418 additional_bw = sched_config.additional_bw();
2419 priority = sched_config.priority();
2420 weight = sched_config.weight();
2421 sched_policy = sched_config.sched_policy();
2422 traffic_shaping_info = traffic_sched.traffic_shaping_info();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002423 tech_profile_id = traffic_sched.tech_profile_id();
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002424 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002425 sched_policy, traffic_shaping_info, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002426 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002427 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002428 return bcm_to_grpc_err(err, "Failed to create scheduler");
2429 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002430 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002431 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002432}
Jonathan Davis70c21812018-07-19 15:32:10 -04002433
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002434bcmos_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 -04002435
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002436 bcmos_errno err;
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302437 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302438 bcmolt_status los_status;
Girish Gowdra96461052019-11-22 20:13:59 +05302439 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002440
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002441 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002442 bcmolt_itupon_alloc_cfg cfg;
2443 bcmolt_itupon_alloc_key key = { };
2444 key.pon_ni = intf_id;
2445 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302446 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002447
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002448 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002449 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2450 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002451 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2452 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002453 return err;
2454 }
Girish Gowdra96461052019-11-22 20:13:59 +05302455
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302456 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302457 if (err == BCM_ERR_OK) {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302458 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_OFF) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002459#ifndef SCALE_AND_PERF
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302460 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 +05302461 intf_id);
2462 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2463 if (err) {
2464 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2465 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
2466 return err;
2467 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002468#endif
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302469 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302470 else if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_ON) {
2471 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is enabled but LoS status is ON, not waiting for alloc cfg clear response\n",
2472 intf_id);
2473 }
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302474 else if (state == BCMOLT_INTERFACE_STATE_INACTIVE) {
2475 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is disabled, not waiting for alloc cfg clear response\n",
2476 intf_id);
2477 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302478 } else {
2479 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 +05302480 intf_id, bcmos_strerror(err));
Girish Gowdra96461052019-11-22 20:13:59 +05302481 return err;
2482 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002483 } else if (direction == downstream) {
2484 bcmolt_tm_sched_cfg cfg;
2485 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002486
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002487 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2488 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302489 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002490 } else {
2491 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2492 return BCM_ERR_OK;
2493 }
Girish Gowdra96461052019-11-22 20:13:59 +05302494
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002495 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2496 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2497 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002498 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002499intf_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 +00002500 return err;
2501 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002502 }
2503
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002504 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d, tech_profile_id %d\n",
2505 direction.c_str(), sched_id, intf_id, onu_id, tech_profile_id);
2506 free_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002507 return BCM_ERR_OK;
2508}
2509
Girish Gowdra252f4972020-09-07 21:24:01 -07002510Status RemoveTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002511 uint32_t intf_id = traffic_scheds->intf_id();
2512 uint32_t onu_id = traffic_scheds->onu_id();
2513 uint32_t uni_id = traffic_scheds->uni_id();
2514 std::string direction;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002515 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002516 bcmos_errno err;
2517
2518 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002519 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002520
2521 direction = GetDirection(traffic_sched.direction());
2522 if (direction.compare("direction-not-supported") == 0)
2523 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2524
2525 int alloc_id = traffic_sched.alloc_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002526 int tech_profile_id = traffic_sched.tech_profile_id();
2527 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002528 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002529 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002530 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2531 }
2532 }
2533 return Status::OK;
2534}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002535
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002536bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2537 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002538 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002539 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2540 bcmolt_tm_qmp_key tm_qmp_key;
2541 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002542
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002543 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2544 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002545 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed tm queue mapping profile count is 16.\n");
2546 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002547 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002548
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002549 tm_qmp_key.id = tm_qmp_id;
2550 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2551 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2552 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002553
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002554 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2555 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2556 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002557 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2558 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002559
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002560 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002561 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002562 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2563 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002564 return err;
2565 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002566
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002567 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2568 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002569 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002570}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002571
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002572bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2573 bcmos_errno err;
2574 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2575 bcmolt_tm_qmp_key tm_qmp_key;
2576 tm_qmp_key.id = tm_qmp_id;
2577
2578 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2579 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2580 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002581 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2582 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002583 return err;
2584 }
2585
2586 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2587 tm_qmp_key.id);
2588 return BCM_ERR_OK;
2589}
2590
2591bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2592 bcmos_errno err;
2593
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002594 /* Create default queues on the given PON/NNI scheduler */
2595 for (int queue_id = 0; queue_id < NUMBER_OF_DEFAULT_INTERFACE_QUEUES; queue_id++) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002596 bcmolt_tm_queue_cfg tm_queue_cfg;
2597 bcmolt_tm_queue_key tm_queue_key = {};
2598 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2599 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002600 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2601 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2602 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002603
2604 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2605 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2606 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2607
2608 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2609 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002610 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", \
2611 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 +00002612 return err;
2613 }
2614
2615 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2616 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2617 }
2618 return BCM_ERR_OK;
2619}
2620
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002621bcmos_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 +00002622 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 +00002623 bcmos_errno err;
2624 bcmolt_tm_queue_cfg cfg;
2625 bcmolt_tm_queue_key key = { };
2626 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 +00002627gemport_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 +00002628
2629 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002630 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002631
2632 if (priority > 7) {
2633 return BCM_ERR_RANGE;
2634 }
2635
2636 /* FIXME: The upstream queues have to be created once only.
2637 The upstream queues on the NNI scheduler are shared by all subscribers.
2638 When the first scheduler comes in, the queues get created, and are re-used by all others.
2639 Also, these queues should be present until the last subscriber exits the system.
2640 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2641
2642 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2643 for each GEM in TECH PROFILE */
2644 key.id = queue_id_list[priority];
2645
2646 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2647 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2648 key.id = 0;
2649 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2650 }
2651 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2652 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2653 }
2654 else {
2655 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2656 }
2657
2658 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2659
2660 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2661 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
2662
2663 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2664 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002665 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002666sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, tech_profile_id %d, err = %s\n", \
2667 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 +00002668 return err;
2669 }
2670
Girish Gowdra252f4972020-09-07 21:24:01 -07002671 if (direction.compare(upstream) == 0) {
2672 Status st = install_gem_port(access_intf_id, onu_id, gemport_id);
2673 if (st.error_code() != grpc::StatusCode::ALREADY_EXISTS && st.error_code() != grpc::StatusCode::OK) {
2674 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);
2675 return BCM_ERR_INTERNAL;
2676 }
2677 }
2678
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002679 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 +00002680intf_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 +00002681 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002682}
2683
Girish Gowdra252f4972020-09-07 21:24:01 -07002684Status CreateTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002685 uint32_t intf_id = traffic_queues->intf_id();
2686 uint32_t onu_id = traffic_queues->onu_id();
2687 uint32_t uni_id = traffic_queues->uni_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002688 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002689 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002690 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002691 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002692 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 +00002693
2694 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2695 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2696 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2697 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002698 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002699
2700 direction = GetDirection(traffic_queue.direction());
2701 if (direction.compare("direction-not-supported") == 0)
2702 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2703
2704 queues_priority_q[i] = traffic_queue.priority();
2705 queues_pbit_map[i] = traffic_queue.pbit_map();
2706 }
2707
2708 std::vector<uint32_t> tmq_map_profile(8, 0);
2709 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2710 queues_priority_q, COUNT_OF(queues_priority_q));
2711 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002712 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002713
2714 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2715 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002716 err = CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2717 if (err != BCM_ERR_OK) {
2718 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2719 return bcm_to_grpc_err(err, "Failed to create tm queue mapping profile");
2720 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002721 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2722 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2723 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2724 }
2725 }
2726
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002727 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002728 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002729
2730 direction = GetDirection(traffic_queue.direction());
2731 if (direction.compare("direction-not-supported") == 0)
2732 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2733
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002734 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 +00002735
Girish Gowdruf26cf882019-05-01 23:47:58 -07002736 // If the queue exists already, lets not return failure and break the loop.
2737 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002738 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002739 return bcm_to_grpc_err(err, "Failed to create queue");
2740 }
2741 }
2742 return Status::OK;
2743}
2744
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002745bcmos_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 +00002746 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 +00002747 bcmolt_tm_queue_cfg cfg;
2748 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002749 bcmos_errno err;
2750
2751 if (direction == downstream) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002752 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2753 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 +00002754 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002755 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002756 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 -08002757 return BCM_ERR_OK;
2758 }
2759 } else {
Girish Gowdra4fd30672020-11-09 17:23:06 -08002760 // Gemports are bi-directional (except in multicast case). We create the gem port when we create the
2761 // upstream queue (see CreateQueue function) and it makes sense to delete them when remove the upstream queues.
2762 // For multicast case we do not manage the install/remove of gem port in agent application. It is managed by BAL.
2763 // Moreover it also makes sense to remove when upstream queue is getting removed because the upstream queue MUST exist always.
2764 // It is possible that the downstream queues are not created for a subscriber (for ex: upstream EAPoL trap flow only exists
2765 // but no other flow, and in this case only upstream scheduler and queues exist. We do not have a scenario where only downstream
2766 // subscriber flows exist but no upstream )
2767 remove_gem_port(access_intf_id, gemport_id);
2768
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002769 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2770 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002771 return BCM_ERR_OK;
2772 }
2773
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002774 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2775 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2776 // Reset the queue id to 0 when using fixed queue.
2777 key.id = 0;
2778 }
2779 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2780 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2781 }
2782 else {
2783 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2784 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002785
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002786 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2787 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002788 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002789 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, queue_id %d, sched_id %d, \
2790tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n",
2791 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 -08002792 return err;
2793 }
2794
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002795 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2796intf_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 -08002797
2798 return BCM_ERR_OK;
2799}
2800
Girish Gowdra252f4972020-09-07 21:24:01 -07002801Status RemoveTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002802 uint32_t intf_id = traffic_queues->intf_id();
2803 uint32_t onu_id = traffic_queues->onu_id();
2804 uint32_t uni_id = traffic_queues->uni_id();
2805 uint32_t port_no = traffic_queues->port_no();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002806 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002807 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002808 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002809 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002810 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 +00002811
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002812 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002813 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002814
2815 direction = GetDirection(traffic_queue.direction());
2816 if (direction.compare("direction-not-supported") == 0)
2817 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2818
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002819 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 -08002820 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002821 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002822 return bcm_to_grpc_err(err, "Failed to remove queue");
2823 }
Jonathan Davis70c21812018-07-19 15:32:10 -04002824 }
2825
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002826 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 +00002827 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002828 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002829
2830 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
2831 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002832 err = RemoveTrafficQueueMappingProfile(tm_qmp_id);
2833 if (err != BCM_ERR_OK) {
2834 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2835 return bcm_to_grpc_err(err, "Failed to remove tm queue mapping profile");
2836 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002837 }
2838 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002839 clear_qos_type(intf_id, onu_id, uni_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04002840 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04002841}
Jason Huangbf45ffb2019-10-30 17:29:02 +08002842
Girish Gowdra252f4972020-09-07 21:24:01 -07002843Status PerformGroupOperation_(const ::openolt::Group *group_cfg) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002844
2845 bcmos_errno err;
2846 bcmolt_group_key key = {};
2847 bcmolt_group_cfg grp_cfg_obj;
2848 bcmolt_group_members_update grp_mem_upd;
2849 bcmolt_members_update_command grp_mem_upd_cmd;
2850 bcmolt_group_member_info member_info = {};
2851 bcmolt_group_member_info_list_u8 members = {};
2852 bcmolt_intf_ref interface_ref = {};
2853 bcmolt_egress_qos egress_qos = {};
2854 bcmolt_tm_sched_ref tm_sched_ref = {};
2855 bcmolt_action a_val = {};
2856
2857 uint32_t group_id = group_cfg->group_id();
2858
2859 OPENOLT_LOG(INFO, openolt_log_id, "PerformGroupOperation request received for Group %d\n", group_id);
2860
2861 if (group_id >= 0) {
2862 key.id = group_id;
2863 }
2864 else {
2865 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
2866 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
2867 }
2868
2869 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2870 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
2871
2872 OPENOLT_LOG(INFO, openolt_log_id, "Checking if Group %d exists...\n",group_id);
2873
2874 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
2875 if (err != BCM_ERR_OK) {
2876 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
2877 return bcm_to_grpc_err(err, "Error in querying group");
2878 }
2879
2880 members.len = group_cfg->members_size();
2881
2882 // IMPORTANT: A member cannot be added to a group if the group type is not determined.
2883 // Group type is determined after a flow is assigned to it.
2884 // Therefore, a group must be created first, then a flow (with multicast type) must be assigned to it.
2885 // Only then we can add members to the group.
2886
2887 // if group does not exist, create it and return.
2888 if (grp_cfg_obj.data.state == BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
2889
2890 if (members.len != 0) {
2891 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);
2892 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Non-empty member list given for non-existent group");
2893 } else {
2894
2895 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2896 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, cookie, key.id);
2897
2898 /* Setting group actions and action parameters, if any.
2899 Only remove_outer_tag and translate_inner_tag actions and i_vid action parameter
2900 are supported for multicast groups in BAL 3.1.
2901 */
2902 const ::openolt::Action& action = group_cfg->action();
2903 const ::openolt::ActionCmd &cmd = action.cmd();
2904
2905 bcmolt_action_cmd_id cmd_bmask = BCMOLT_ACTION_CMD_ID_NONE;
2906 if (cmd.remove_outer_tag()) {
2907 OPENOLT_LOG(INFO, openolt_log_id, "Action remove_outer_tag applied to Group %d.\n", group_id);
2908 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
2909 }
2910
2911 if (cmd.translate_inner_tag()) {
2912 OPENOLT_LOG(INFO, openolt_log_id, "Action translate_inner_tag applied to Group %d.\n", group_id);
2913 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG);
2914 }
2915
2916 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, cmd_bmask);
2917
2918 if (action.i_vid()) {
2919 OPENOLT_LOG(INFO, openolt_log_id, "Setting action parameter i_vid=%d for Group %d.\n", action.i_vid(), group_id);
2920 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
2921 }
2922
2923 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, action, a_val);
2924
2925 // Create group
2926 err = bcmolt_cfg_set(dev_id, &(grp_cfg_obj.hdr));
2927
2928 if (BCM_ERR_OK != err) {
2929 BCM_LOG(ERROR, openolt_log_id, "Failed to create Group %d, err = %s (%d)\n", key.id, bcmos_strerror(err), err);
2930 return bcm_to_grpc_err(err, "Error in creating group");
2931 }
2932
2933 BCM_LOG(INFO, openolt_log_id, "Group %d has been created and configured with empty member list.\n", key.id);
2934 return Status::OK;
2935 }
2936 }
2937
2938 // The group already exists. Continue configuring it according to the update member command.
2939
2940 OPENOLT_LOG(INFO, openolt_log_id, "Configuring existing Group %d.\n",group_id);
2941
2942 // MEMBER LIST CONSTRUCTION
2943 // Note that members.len can be 0 here. if the group already exists and the command is SET then sending
2944 // empty list to the group is a legit operation and this actually empties the member list.
2945 members.arr = (bcmolt_group_member_info*)bcmos_calloc((members.len)*sizeof(bcmolt_group_member_info));
2946
2947 if (!members.arr) {
2948 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to allocate memory for group member list.\n");
2949 return grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "Memory exhausted during member list creation");
2950 }
2951
2952 /* SET GROUP MEMBERS UPDATE COMMAND */
Girish Gowdra252f4972020-09-07 21:24:01 -07002953 ::openolt::Group::GroupMembersCommand command = group_cfg->command();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002954 switch(command) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002955 case ::openolt::Group::SET_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002956 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_SET;
2957 OPENOLT_LOG(INFO, openolt_log_id, "Setting %d members for Group %d.\n", members.len, group_id);
2958 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07002959 case ::openolt::Group::ADD_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002960 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_ADD;
2961 OPENOLT_LOG(INFO, openolt_log_id, "Adding %d members to Group %d.\n", members.len, group_id);
2962 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07002963 case ::openolt::Group::REMOVE_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002964 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_REMOVE;
2965 OPENOLT_LOG(INFO, openolt_log_id, "Removing %d members from Group %d.\n", members.len, group_id);
2966 break;
2967 default :
2968 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid value %d for group member command.\n", command);
2969 bcmos_free(members.arr);
2970 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group member command");
2971 }
2972
2973 // SET MEMBERS LIST
2974 for (int i = 0; i < members.len; i++) {
2975
Girish Gowdra252f4972020-09-07 21:24:01 -07002976 if (command == ::openolt::Group::REMOVE_MEMBERS) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002977 OPENOLT_LOG(INFO, openolt_log_id, "Removing group member %d from group %d\n",i,key.id);
2978 } else {
2979 OPENOLT_LOG(INFO, openolt_log_id, "Adding group member %d to group %d\n",i,key.id);
2980 }
2981
Girish Gowdra252f4972020-09-07 21:24:01 -07002982 ::openolt::GroupMember *member = (::openolt::GroupMember *) &group_cfg->members()[i];
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002983
2984 // Set member interface type
Girish Gowdra252f4972020-09-07 21:24:01 -07002985 ::openolt::GroupMember::InterfaceType if_type = member->interface_type();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002986 switch(if_type){
Girish Gowdra252f4972020-09-07 21:24:01 -07002987 case ::openolt::GroupMember::PON :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002988 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_PON);
2989 OPENOLT_LOG(INFO, openolt_log_id, "Interface type PON is assigned to GroupMember %d\n",i);
2990 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07002991 case ::openolt::GroupMember::EPON_1G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002992 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_1_G);
2993 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_1G is assigned to GroupMember %d\n",i);
2994 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07002995 case ::openolt::GroupMember::EPON_10G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002996 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_10_G);
2997 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_10G is assigned to GroupMember %d\n",i);
2998 break;
2999 default :
3000 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid interface type value %d for GroupMember %d.\n",if_type,i);
3001 bcmos_free(members.arr);
3002 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface type for a group member");
3003 }
3004
3005 // Set member interface id
3006 if (member->interface_id() >= 0) {
3007 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_id, member->interface_id());
3008 OPENOLT_LOG(INFO, openolt_log_id, "Interface %d is assigned to GroupMember %d\n", member->interface_id(), i);
3009 } else {
3010 bcmos_free(members.arr);
3011 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface id for a group member");
3012 }
3013
3014 // Set member interface_ref
3015 BCMOLT_FIELD_SET(&member_info, group_member_info, intf, interface_ref);
3016
3017 // Set member gem_port_id. This must be a multicast gemport.
3018 if (member->gem_port_id() >= 0) {
3019 BCMOLT_FIELD_SET(&member_info, group_member_info, svc_port_id, member->gem_port_id());
3020 OPENOLT_LOG(INFO, openolt_log_id, "GEM Port %d is assigned to GroupMember %d\n", member->gem_port_id(), i);
3021 } else {
3022 bcmos_free(members.arr);
3023 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid gem port id for a group member");
3024 }
3025
3026 // Set member scheduler id and queue_id
3027 uint32_t tm_sched_id = get_default_tm_sched_id(member->interface_id(), downstream);
3028 OPENOLT_LOG(INFO, openolt_log_id, "Scheduler %d is assigned to GroupMember %d\n", tm_sched_id, i);
3029 BCMOLT_FIELD_SET(&tm_sched_ref, tm_sched_ref, id, tm_sched_id);
3030 BCMOLT_FIELD_SET(&egress_qos, egress_qos, tm_sched, tm_sched_ref);
3031
3032 // We assume that all multicast traffic destined to a PON port is using the same fixed queue.
3033 uint32_t tm_queue_id;
3034 if (member->priority() >= 0 && member->priority() < NUMBER_OF_DEFAULT_INTERFACE_QUEUES) {
3035 tm_queue_id = queue_id_list[member->priority()];
3036 OPENOLT_LOG(INFO, openolt_log_id, "Queue %d is assigned to GroupMember %d\n", tm_queue_id, i);
3037 BCMOLT_FIELD_SET(&egress_qos, egress_qos, type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
3038 BCMOLT_FIELD_SET(&egress_qos.u.fixed_queue, egress_qos_fixed_queue, queue_id, tm_queue_id);
3039 } else {
3040 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid fixed queue priority/ID %d for GroupMember %d\n", member->priority(), i);
3041 bcmos_free(members.arr);
3042 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid queue priority for a group member");
3043 }
3044
3045 BCMOLT_FIELD_SET(&member_info, group_member_info, egress_qos, egress_qos);
3046 BCMOLT_ARRAY_ELEM_SET(&(members), i, member_info);
3047 }
3048
3049 BCMOLT_OPER_INIT(&grp_mem_upd, group, members_update, key);
3050 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.members, members);
3051 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.command, grp_mem_upd_cmd);
3052
3053 err = bcmolt_oper_submit(dev_id, &(grp_mem_upd.hdr));
3054 bcmos_free(members.arr);
3055
3056 if (BCM_ERR_OK != err) {
3057 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);
3058 return bcm_to_grpc_err(err, "Failed to submit members update operation for the group");
3059 }
3060
3061 OPENOLT_LOG(INFO, openolt_log_id, "Successfully submitted members update operation for Group %d\n", key.id);
3062
3063 return Status::OK;
3064}
Burak Gurdageb4ca2e2020-06-15 07:48:26 +00003065
3066Status DeleteGroup_(uint32_t group_id) {
3067
3068 bcmos_errno err = BCM_ERR_OK;
3069 bcmolt_group_cfg grp_cfg_obj;
3070 bcmolt_group_key key = {};
3071
3072
3073 OPENOLT_LOG(INFO, openolt_log_id, "Delete request received for group %d\n", group_id);
3074
3075 if (group_id >= 0) {
3076 key.id = group_id;
3077 } else {
3078 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
3079 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
3080 }
3081
3082 /* init the BAL INIT API */
3083 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3084
3085 OPENOLT_LOG(DEBUG, openolt_log_id, "Checking if group %d exists...\n",group_id);
3086
3087 // CONFIGURE GROUP MEMBERS
3088 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
3089 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
3090
3091 if (err != BCM_ERR_OK) {
3092 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
3093 return bcm_to_grpc_err(err, "Error in querying group");
3094 }
3095
3096 if (grp_cfg_obj.data.state != BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
3097 OPENOLT_LOG(DEBUG, openolt_log_id, "Group %d exists. Will be deleted.\n",group_id);
3098 err = bcmolt_cfg_clear(dev_id, &(grp_cfg_obj.hdr));
3099 if (err != BCM_ERR_OK) {
3100 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d cannot be deleted err = %s (%d).\n", group_id, bcmos_strerror(err), err);
3101 return bcm_to_grpc_err(err, "Failed to delete group");;
3102 }
3103 } else {
3104 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d does not exist.\n", group_id);
3105 return Status(grpc::StatusCode::NOT_FOUND, "Group not found");
3106 }
3107
3108 OPENOLT_LOG(INFO, openolt_log_id, "Group %d has been deleted successfully.\n", group_id);
3109 return Status::OK;
Jason Huang1d9cfce2020-05-20 22:58:47 +08003110}
3111
Girish Gowdra252f4972020-09-07 21:24:01 -07003112Status GetLogicalOnuDistanceZero_(uint32_t intf_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003113 bcmos_errno err = BCM_ERR_OK;
3114 uint32_t mld = 0;
3115 double LD0;
3116
3117 err = getOnuMaxLogicalDistance(intf_id, &mld);
3118 if (err != BCM_ERR_OK) {
3119 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3120 }
3121
3122 LD0 = LOGICAL_DISTANCE(mld*1000, MINIMUM_ONU_RESPONSE_RANGING_TIME, ONU_BIT_TRANSMISSION_DELAY);
3123 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance zero is %f, (PON %d)\n", LD0, intf_id);
3124 response->set_intf_id(intf_id);
3125 response->set_logical_onu_distance_zero(LD0);
3126
3127 return Status::OK;
3128}
3129
Girish Gowdra252f4972020-09-07 21:24:01 -07003130Status GetLogicalOnuDistance_(uint32_t intf_id, uint32_t onu_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003131 bcmos_errno err = BCM_ERR_OK;
3132 bcmolt_itu_onu_params itu = {};
3133 bcmolt_onu_cfg onu_cfg;
3134 bcmolt_onu_key onu_key = {};
3135 uint32_t mld = 0;
3136 double LDi;
3137
3138 onu_key.pon_ni = intf_id;
3139 onu_key.onu_id = onu_id;
3140
3141 err = getOnuMaxLogicalDistance(intf_id, &mld);
3142 if (err != BCM_ERR_OK) {
3143 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3144 }
3145
3146 /* Initialize the API struct. */
3147 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
3148 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
3149 BCMOLT_FIELD_SET_PRESENT(&itu, itu_onu_params, ranging_time);
3150 BCMOLT_FIELD_SET(&onu_cfg.data, onu_cfg_data, itu, itu);
3151 #ifdef TEST_MODE
3152 // It is impossible to mock the setting of onu_cfg.data.onu_state because
3153 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
3154 // set the onu_cfg.data.onu_state. So a new stub function is created and address
3155 // of onu_cfg is passed. This is one-of case where we need to add test specific
3156 // code in production code.
3157 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
3158 #else
3159 /* Call API function. */
3160 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
3161 #endif
3162 if (err != BCM_ERR_OK) {
3163 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);
3164 return bcm_to_grpc_err(err, "Failed to retrieve ONU ranging time");
3165 }
3166
3167 if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_ACTIVE) {
3168 OPENOLT_LOG(ERROR, openolt_log_id, "ONU is not yet activated (PON %d, ONU id %d)\n", intf_id, onu_id);
3169 return bcm_to_grpc_err(BCM_ERR_PARM, "ONU is not yet activated\n");
3170 }
3171
3172 LDi = LOGICAL_DISTANCE(mld*1000, onu_cfg.data.itu.ranging_time, ONU_BIT_TRANSMISSION_DELAY);
3173 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance is %f, (PON %d, ONU id %d)\n", LDi, intf_id, onu_id);
3174 response->set_intf_id(intf_id);
3175 response->set_onu_id(onu_id);
3176 response->set_logical_onu_distance(LDi);
3177
3178 return Status::OK;
3179}