blob: 2c5ff836b59f7d465c56d714c0fc0ceb0dc0e2b4 [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,
Girish Gowdrade65ab42020-12-17 23:08:43 -08001541 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Girish Gowdra252f4972020-09-07 21:24:01 -07001542 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
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001759 if (classifier.dst_ip()) {
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08001760 bcmos_ipv4_address d_ip = {};
1761 bcmos_ipv4_address_init(&d_ip);
1762 d_ip.u32 = classifier.dst_ip();
1763 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_ip %04x\n", d_ip.u32);
1764 BCMOLT_FIELD_SET(&c_val, classifier, dst_ip, d_ip);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001765 }
1766
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08001767 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001768 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001769 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001770 }
1771 */
1772
1773 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001774 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
1775 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001776 }
1777
1778 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001779 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
1780 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001781 }
1782
1783 if (!classifier.pkt_tag_type().empty()) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001784 if (classifier.o_vid()) {
1785 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
1786 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
1787 }
1788
1789 if (classifier.i_vid()) {
1790 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
1791 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
1792 }
1793
1794 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
1795 if (classifier.pkt_tag_type().compare("untagged") == 0) {
1796 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
1797 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
1798 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
1799 single_tag = true;
1800
1801 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301802 // OpenOlt adapter will send 0xFF in case of no pbit classification
1803 // If it is any other value (0 to 7), it is for outer pbit classification.
1804 // OpenFlow protocol does not provide inner pbit classification (in case of double tagged packets),
1805 // and VOLTHA has not used any workaround to solve this problem (for ex: use metadata field).
1806 // Also there exists no use case for i-pbit classification, so we can safely ignore this for now.
1807 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001808 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301809 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001810 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
1811 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001812
Jason Huang09b73ea2020-01-08 17:52:05 +08001813 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301814 // Same comments as in case of "single_tag" packets.
1815 // 0xFF means no pbit classification, otherwise a valid PCP (0 to 7).
1816 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001817 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301818 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001819 }
1820 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001821 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001822 }
1823
Jason Huang09b73ea2020-01-08 17:52:05 +08001824 const ::openolt::ActionCmd& cmd = action.cmd();
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001825
Jason Huang09b73ea2020-01-08 17:52:05 +08001826 if (cmd.add_outer_tag()) {
1827 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
1828 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001829 }
1830
Jason Huang09b73ea2020-01-08 17:52:05 +08001831 if (cmd.remove_outer_tag()) {
1832 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
1833 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
1834 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301835
Jason Huang09b73ea2020-01-08 17:52:05 +08001836 if (action.o_vid()) {
1837 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
1838 o_vid = action.o_vid();
1839 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
1840 }
1841
1842 if (action.o_pbits()) {
1843 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
1844 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
1845 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301846
Jason Huang09b73ea2020-01-08 17:52:05 +08001847 if (action.i_vid()) {
1848 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
1849 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
1850 }
1851
1852 if (action.i_pbits()) {
1853 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
1854 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
1855 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301856
Jason Huang09b73ea2020-01-08 17:52:05 +08001857 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
1858
Shad Ansari39739bc2018-09-13 21:38:37 +00001859 if ((access_intf_id >= 0) && (onu_id >= 0)) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001860 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
1861 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00001862 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 +00001863
Jason Huang09b73ea2020-01-08 17:52:05 +08001864 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1865 // Queue 0 on DS subscriber scheduler
1866 tm_val.queue_id = 0;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001867
Jason Huang09b73ea2020-01-08 17:52:05 +08001868 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1869 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1870 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001871
Jason Huang09b73ea2020-01-08 17:52:05 +08001872 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1873 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1874 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001875
Jason Huang09b73ea2020-01-08 17:52:05 +08001876 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1877 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
1878 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 +00001879
Jason Huang09b73ea2020-01-08 17:52:05 +08001880 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1881 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1882 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1883 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 +00001884
Jason Huang09b73ea2020-01-08 17:52:05 +08001885 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
1886 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1887 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1888 }
1889 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
1890 // NNI Scheduler ID
1891 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1892 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1893 // Queue 0 on NNI scheduler
1894 tm_val.queue_id = 0;
1895 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1896 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1897 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001898
Jason Huang09b73ea2020-01-08 17:52:05 +08001899 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 +00001900 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1901 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1902
Jason Huang09b73ea2020-01-08 17:52:05 +08001903 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1904 /* Fetch TM QMP ID mapped to US NNI scheduler */
1905 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
1906 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1907 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1908 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1909 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 +00001910
Jason Huang09b73ea2020-01-08 17:52:05 +08001911 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 +00001912 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1913 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001914 }
Shad Ansari39739bc2018-09-13 21:38:37 +00001915 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301916 } else {
1917 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1918 tm_val.queue_id = 0;
1919
1920 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
1921 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1922 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
1923
1924 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1925 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
1926 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00001927 }
1928
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001929 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001930
Girish Gowdra252f4972020-09-07 21:24:01 -07001931#ifndef SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001932 // BAL 3.1 supports statistics only for unicast flows.
1933 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1934 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
1935 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001936#endif // SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001937
Girish Gowdra252f4972020-09-07 21:24:01 -07001938#ifndef SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001939#ifdef FLOW_CHECKER
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001940 //Flow Checker, To avoid duplicate flow.
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001941 if (flow_id_counters != 0) {
1942 bool b_duplicate_flow = false;
Jason Huang09b73ea2020-01-08 17:52:05 +08001943 std::map<flow_pair, int>::iterator it;
1944
1945 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1946 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(it->first.first, it->first.second, ONU_ID)) && \
1947 (key.flow_type == it->first.second) && \
1948 (cfg.data.svc_port_id == get_flow_status(it->first.first, it->first.second, SVC_PORT_ID)) && \
1949 (cfg.data.priority == get_flow_status(it->first.first, it->first.second, PRIORITY)) && \
1950 (cfg.data.cookie == get_flow_status(it->first.first, it->first.second, COOKIE)) && \
1951 (cfg.data.ingress_intf.intf_type == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_TYPE)) && \
1952 (cfg.data.ingress_intf.intf_id == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_ID)) && \
1953 (cfg.data.egress_intf.intf_type == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_TYPE)) && \
1954 (cfg.data.egress_intf.intf_id == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_ID)) && \
1955 (c_val.o_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_VID)) && \
1956 (c_val.o_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_PBITS)) && \
1957 (c_val.i_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_VID)) && \
1958 (c_val.i_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_PBITS)) && \
1959 (c_val.ether_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_ETHER_TYPE)) && \
1960 (c_val.ip_proto == get_flow_status(it->first.first, it->first.second, CLASSIFIER_IP_PROTO)) && \
1961 (c_val.src_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_SRC_PORT)) && \
1962 (c_val.dst_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_DST_PORT)) && \
1963 (c_val.pkt_tag_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_PKT_TAG_TYPE)) && \
1964 (cfg.data.egress_qos.type == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TYPE)) && \
1965 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_QUEUE_ID)) && \
1966 (cfg.data.egress_qos.tm_sched.id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TM_SCHED_ID)) && \
1967 (a_val.cmds_bitmask == get_flow_status(it->first.first, it->first.second, ACTION_CMDS_BITMASK)) && \
1968 (a_val.o_vid == get_flow_status(it->first.first, it->first.second, ACTION_O_VID)) && \
1969 (a_val.i_vid == get_flow_status(it->first.first, it->first.second, ACTION_I_VID)) && \
1970 (a_val.o_pbits == get_flow_status(it->first.first, it->first.second, ACTION_O_PBITS)) && \
1971 (a_val.i_pbits == get_flow_status(it->first.first, it->first.second, ACTION_I_PBITS)) && \
1972 (cfg.data.state == get_flow_status(it->first.first, it->first.second, STATE)) && \
1973 (cfg.data.group_id == get_flow_status(it->first.first, it->first.second, GROUP_ID));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001974#ifdef SHOW_FLOW_PARAM
1975 // Flow Parameter
1976 FLOW_PARAM_LOG();
1977#endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001978 if (b_duplicate_flow) {
1979 FLOW_LOG(WARNING, "Flow duplicate", 0);
1980 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
1981 }
1982 }
1983 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001984#endif // FLOW_CHECKER
1985#endif // SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001986
1987 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
1988 if (err) {
1989 FLOW_LOG(ERROR, "Flow add failed", err);
1990 return bcm_to_grpc_err(err, "flow add failed");
1991 } else {
1992 FLOW_LOG(INFO, "Flow add ok", err);
1993 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08001994 flow_map[std::pair<int, int>(key.flow_id,key.flow_type)] = flow_map.size();
1995 flow_id_counters = flow_map.size();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001996 bcmos_fastlock_unlock(&data_lock, 0);
Girish Gowdra252f4972020-09-07 21:24:01 -07001997
1998 }
1999 return Status::OK;
2000}
2001
2002Status FlowRemoveWrapper_(const ::openolt::Flow* request) {
2003 const std::string flow_type = request->flow_type();
2004 uint64_t voltha_flow_id = request->flow_id();
2005 Status st;
2006
2007 // If Voltha flow is not installed, return fail
2008 if (! is_voltha_flow_installed(voltha_flow_id)) {
2009 OPENOLT_LOG(ERROR, openolt_log_id, "voltha_flow_id=%lu not found\n", voltha_flow_id);
2010 return ::Status(grpc::StatusCode::NOT_FOUND, "voltha-flow-not-found");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002011 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04002012
Girish Gowdra252f4972020-09-07 21:24:01 -07002013 const device_flow *dev_fl = get_device_flow(voltha_flow_id);
2014 if (dev_fl == NULL) {
2015 OPENOLT_LOG(ERROR, openolt_log_id, "device flow for voltha_flow_id=%lu in the cache is NULL\n", voltha_flow_id);
2016 return ::Status(grpc::StatusCode::INTERNAL, "device-flow-null-in-cache");
2017 }
2018 if (dev_fl->is_flow_replicated) {
2019 // Note: Here we are ignoring FlowRemove failures
2020 for (int i=0; i<NUMBER_OF_REPLICATED_FLOWS; i++) {
2021 st = FlowRemove_(dev_fl->params[i].flow_id, flow_type);
2022 if (st.error_code() == grpc::StatusCode::OK) {
2023 free_flow_id(dev_fl->params[i].flow_id);
2024 }
2025 }
2026 } else {
2027 // Note: Here we are ignoring FlowRemove failures
2028 st = FlowRemove_(dev_fl->params[0].flow_id, flow_type);
2029 if (st.error_code() == grpc::StatusCode::OK) {
2030 free_flow_id(dev_fl->params[0].flow_id);
2031 }
2032 }
2033 // remove the flow from cache on voltha flow removal
2034 remove_voltha_flow_from_cache(voltha_flow_id);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002035 return Status::OK;
2036}
2037
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002038Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
2039
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002040 bcmolt_flow_cfg cfg;
2041 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002042
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002043 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002044 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002045 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002046 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002047 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002048 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002049 } else if(flow_type.compare(multicast) == 0) {
2050 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002051 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002052 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002053 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
2054 }
2055
Jason Huang09b73ea2020-01-08 17:52:05 +08002056 OPENOLT_LOG(INFO, openolt_log_id, "flow remove received for flow_id=%u, flow_type=%s\n",
2057 flow_id, flow_type.c_str());
2058
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002059 bcmos_fastlock_lock(&acl_packet_trap_handler_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002060 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
2061 int32_t gemport_id = -1;
2062 int32_t intf_id = -1;
2063 int16_t acl_id = -1;
2064 if (flow_to_acl_map.count(fl_id_fl_dir) > 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002065
2066 acl_id_intf_id ac_id_if_id = flow_to_acl_map[fl_id_fl_dir];
2067 acl_id = std::get<0>(ac_id_if_id);
2068 intf_id = std::get<1>(ac_id_if_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002069 // cleanup acl only if it is a valid acl. If not valid acl, it may be datapath flow.
2070 if (acl_id >= 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002071 Status resp = handle_acl_rule_cleanup(acl_id, intf_id, flow_type);
Jason Huang09b73ea2020-01-08 17:52:05 +08002072 if (resp.ok()) {
2073 OPENOLT_LOG(INFO, openolt_log_id, "acl removed ok for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2074 flow_to_acl_map.erase(fl_id_fl_dir);
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002075
2076 // 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
2077 if (trap_to_host_pkt_info_with_vlan_for_flow_id.count(flow_id) > 0) {
2078 trap_to_host_pkt_info_with_vlan pkt_info_with_vlan = trap_to_host_pkt_info_with_vlan_for_flow_id[flow_id];
2079 // Formulate the trap_to_host_pkt_info tuple key
2080 trap_to_host_pkt_info pkt_info(std::get<0>(pkt_info_with_vlan),
2081 std::get<1>(pkt_info_with_vlan),
2082 std::get<2>(pkt_info_with_vlan),
2083 std::get<3>(pkt_info_with_vlan));
2084 // Extract the value corresponding to trap_to_host_pkt_info key from trap_to_host_vlan_ids_for_trap_to_host_pkt_info
2085 // The value is a list of vlan_ids for the given trap_to_host_pkt_info key
2086 // Remove the vlan_id from the list that corresponded to the flow being removed.
2087 if (trap_to_host_vlan_ids_for_trap_to_host_pkt_info.count(pkt_info) > 0) {
2088 trap_to_host_vlan_ids_for_trap_to_host_pkt_info[pkt_info].remove(std::get<4>(pkt_info_with_vlan));
2089 } else {
2090 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",
2091 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));
2092 }
2093
2094 } else {
2095 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);
2096 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002097 } else {
2098 OPENOLT_LOG(ERROR, openolt_log_id, "acl remove error for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
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 return resp;
2102 }
2103 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002104 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002105
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002106 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002107 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002108 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002109 flowid_to_gemport.erase(key.flow_id);
2110 port_to_flows[port_no].erase(key.flow_id);
2111 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
2112 }
2113 else
2114 {
2115 flowid_to_port.erase(key.flow_id);
2116 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002117 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002118
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002119 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002120
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002121 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002122 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002123 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 -04002124 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
2125 }
2126
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002127 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002128 if (flow_id_counters != 0) {
2129 std::map<flow_pair, int>::iterator it;
2130 for(it = flow_map.begin(); it != flow_map.end(); it++) {
2131 if (it->first.first == flow_id && it->first.second == key.flow_type) {
2132 flow_id_counters -= 1;
2133 flow_map.erase(it);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002134 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002135 }
2136 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002137 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
2138
Jason Huang09b73ea2020-01-08 17:52:05 +08002139 flow_to_acl_map.erase(fl_id_fl_dir);
2140
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002141 bcmos_fastlock_unlock(&data_lock, 0);
2142
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002143 return Status::OK;
2144}
2145
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002146bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
2147 bcmos_errno err;
2148 bcmolt_tm_sched_cfg tm_sched_cfg;
2149 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2150 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
2151
Jason Huangbf45ffb2019-10-30 17:29:02 +08002152 //check TM scheduler has configured or not
2153 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2154 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002155 #ifdef TEST_MODE
2156 // It is impossible to mock the setting of tm_sched_cfg.data.state because
2157 // the actual bcmolt_cfg_get passes the address of tm_sched_cfg.hdr and we cannot
2158 // set the tm_sched_cfg.data.state. So a new stub function is created and address
2159 // of tm_sched_cfg is passed. This is one-of case where we need to add test specific
2160 // code in production code.
2161 err = bcmolt_cfg_get__tm_sched_stub(dev_id, &tm_sched_cfg);
2162 #else
Jason Huangbf45ffb2019-10-30 17:29:02 +08002163 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002164 #endif
Jason Huangbf45ffb2019-10-30 17:29:02 +08002165 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002166 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 +08002167 return err;
2168 }
2169 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
2170 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
2171 return BCM_ERR_OK;
2172 }
2173
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002174 // bcmbal_tm_sched_owner
2175 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2176
2177 /**< The output of the tm_sched object instance */
2178 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
2179
2180 if (direction.compare(upstream) == 0) {
2181 // In upstream it is NNI scheduler
2182 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
2183 } else if (direction.compare(downstream) == 0) {
2184 // In downstream it is PON scheduler
2185 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2186 }
2187
2188 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2189
2190 // bcmbal_tm_sched_type
2191 // set the deafult policy to strict priority
2192 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2193
2194 // num_priorities: Max number of strict priority scheduling elements
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002195 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, NUM_OF_PRIORITIES);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002196
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002197 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2198 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002199 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
2200 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002201 return err;
2202 }
2203
2204 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2205 direction.c_str(), tm_sched_key.id, intf_id);
2206 return BCM_ERR_OK;
2207}
2208
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002209bcmos_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 -07002210 uint32_t alloc_id, ::tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
2211 ::tech_profile::SchedulingPolicy sched_policy, ::tech_profile::TrafficShapingInfo tf_sh_info,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002212 uint32_t tech_profile_id) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002213
2214 bcmos_errno err;
2215
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002216 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002217 bcmolt_tm_sched_cfg tm_sched_cfg;
2218 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002219 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 -04002220
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002221 // bcmbal_tm_sched_owner
2222 // In downstream it is sub_term scheduler
2223 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002224
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002225 /**< The output of the tm_sched object instance */
2226 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002227
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002228 // bcmbal_tm_sched_parent
2229 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2230 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
2231 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 +00002232 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002233 be achieved using the' virtual' type of attachment.
2234 tm_sched_owner.u.sub_term.intf_id = intf_id;
2235 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2236 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002237
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002238 // bcmbal_tm_sched_type
2239 // set the deafult policy to strict priority
2240 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002241
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002242 // num_priorities: Max number of strict priority scheduling elements
2243 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002244
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002245 // bcmbal_tm_shaping
2246 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2247 uint32_t cir = tf_sh_info.cir();
2248 uint32_t pir = tf_sh_info.pir();
2249 uint32_t burst = tf_sh_info.pbs();
2250 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2251 cir, pir, burst);
2252 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2253 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2254 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2255 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2256 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2257 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002258 }
2259
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002260 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002261 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002262 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002263intf_id %d, onu_id %d, uni_id %d, port_no %u, err = %s\n", tm_sched_key.id, intf_id, onu_id, uni_id, \
2264port_no, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002265 return err;
2266 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002267 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2268uni_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 -08002269
2270 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002271 bcmolt_itupon_alloc_cfg cfg;
2272 bcmolt_itupon_alloc_key key = { };
2273 key.pon_ni = intf_id;
2274 key.alloc_id = alloc_id;
2275 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
Burak Gurdag03919c72020-02-04 22:46:57 +00002276 int pir_bw = tf_sh_info.pir()*125; // conversion from kbps to bytes/sec
2277 int cir_bw = tf_sh_info.cir()*125; // conversion from kbps to bytes/sec
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002278 //offset to match bandwidth granularity
2279 int offset_pir_bw = pir_bw%bw_granularity;
2280 int offset_cir_bw = cir_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002281
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002282 pir_bw = pir_bw - offset_pir_bw;
2283 cir_bw = cir_bw - offset_cir_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002284
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002285 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002286
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002287 switch (additional_bw) {
2288 case 2: //AdditionalBW_BestEffort
2289 if (pir_bw == 0) {
2290 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2291%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002292 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002293 } else if (pir_bw < cir_bw) {
2294 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2295bandwidth (%d)\n", pir_bw, cir_bw);
2296 return BCM_ERR_PARM;
2297 } else if (pir_bw == cir_bw) {
2298 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2299bandwidth for additional bandwidth eligibility of type best_effort\n");
2300 return BCM_ERR_PARM;
2301 }
2302 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2303 break;
2304 case 1: //AdditionalBW_NA
2305 if (pir_bw == 0) {
2306 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2307%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2308 return BCM_ERR_PARM;
2309 } else if (cir_bw == 0) {
2310 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2311additional bandwidth eligibility of type Non-Assured (NA)\n");
2312 return BCM_ERR_PARM;
2313 } else if (pir_bw < cir_bw) {
2314 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2315bandwidth (%d)\n", pir_bw, cir_bw);
2316 return BCM_ERR_PARM;
2317 } else if (pir_bw == cir_bw) {
2318 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2319bandwidth for additional bandwidth eligibility of type non_assured\n");
2320 return BCM_ERR_PARM;
2321 }
2322 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2323 break;
2324 case 0: //AdditionalBW_None
2325 if (pir_bw == 0) {
2326 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
232716000 bytes/sec\n");
2328 return BCM_ERR_PARM;
2329 } else if (cir_bw == 0) {
2330 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2331for additional bandwidth eligibility of type None\n");
2332 return BCM_ERR_PARM;
2333 } else if (pir_bw > cir_bw) {
2334 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2335for additional bandwidth eligibility of type None\n");
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002336 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002337bandwidth in None eligibility\n", pir_bw);
2338 cir_bw = pir_bw;
2339 } else if (pir_bw < cir_bw) {
2340 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2341bandwidth (%d)\n", pir_bw, cir_bw);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002342 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002343bandwidth in None eligibility\n", pir_bw);
2344 cir_bw = pir_bw;
2345 }
2346 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2347 break;
2348 default:
2349 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002350 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002351 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2352 in a fine granularity. */
2353 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
2354 /* Fixed Bandwidth with no critical requirement of shaping */
2355 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, 0);
2356 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
2357 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, cir_bw);
2358 /* Maximum allocated bandwidth allowed for this alloc ID */
2359 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
2360 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002361 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002362 for skipped allocations during quiet window */
2363 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2364 /**< Allocation Profile index for CBR non-RT Bandwidth */
2365 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2366 /**< Allocation Profile index for CBR RT Bandwidth */
2367 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2368 /**< Alloc ID Weight used in case of Extended DBA mode */
2369 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2370 /**< Alloc ID Priority used in case of Extended DBA mode */
2371 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2372 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002373
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002374 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002375 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002376 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 -05002377port_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 -08002378 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002379 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002380#ifndef SCALE_AND_PERF
Girish Gowdra96461052019-11-22 20:13:59 +05302381 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
2382 if (err) {
2383 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2384port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
2385 return err;
2386 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002387#endif
Girish Gowdra96461052019-11-22 20:13:59 +05302388
2389 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
2390port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
2391
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002392 }
2393
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002394 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002395}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002396
Girish Gowdra252f4972020-09-07 21:24:01 -07002397Status CreateTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002398 uint32_t intf_id = traffic_scheds->intf_id();
2399 uint32_t onu_id = traffic_scheds->onu_id();
2400 uint32_t uni_id = traffic_scheds->uni_id();
2401 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002402 std::string direction;
2403 unsigned int alloc_id;
Girish Gowdra252f4972020-09-07 21:24:01 -07002404 ::tech_profile::SchedulerConfig sched_config;
2405 ::tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002406 uint32_t priority;
2407 uint32_t weight;
Girish Gowdra252f4972020-09-07 21:24:01 -07002408 ::tech_profile::SchedulingPolicy sched_policy;
2409 ::tech_profile::TrafficShapingInfo traffic_shaping_info;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002410 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002411 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002412
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002413 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002414 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002415
2416 direction = GetDirection(traffic_sched.direction());
2417 if (direction.compare("direction-not-supported") == 0)
2418 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2419
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002420 alloc_id = traffic_sched.alloc_id();
2421 sched_config = traffic_sched.scheduler();
2422 additional_bw = sched_config.additional_bw();
2423 priority = sched_config.priority();
2424 weight = sched_config.weight();
2425 sched_policy = sched_config.sched_policy();
2426 traffic_shaping_info = traffic_sched.traffic_shaping_info();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002427 tech_profile_id = traffic_sched.tech_profile_id();
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002428 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002429 sched_policy, traffic_shaping_info, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002430 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002431 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002432 return bcm_to_grpc_err(err, "Failed to create scheduler");
2433 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002434 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002435 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002436}
Jonathan Davis70c21812018-07-19 15:32:10 -04002437
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002438bcmos_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 -04002439
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002440 bcmos_errno err;
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302441 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302442 bcmolt_status los_status;
Girish Gowdra96461052019-11-22 20:13:59 +05302443 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002444
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002445 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002446 bcmolt_itupon_alloc_cfg cfg;
2447 bcmolt_itupon_alloc_key key = { };
2448 key.pon_ni = intf_id;
2449 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302450 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002451
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002452 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002453 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2454 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002455 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2456 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002457 return err;
2458 }
Girish Gowdra96461052019-11-22 20:13:59 +05302459
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302460 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302461 if (err == BCM_ERR_OK) {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302462 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_OFF) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002463#ifndef SCALE_AND_PERF
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302464 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 +05302465 intf_id);
2466 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2467 if (err) {
2468 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2469 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
2470 return err;
2471 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002472#endif
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302473 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302474 else if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_ON) {
2475 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is enabled but LoS status is ON, not waiting for alloc cfg clear response\n",
2476 intf_id);
2477 }
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302478 else if (state == BCMOLT_INTERFACE_STATE_INACTIVE) {
2479 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is disabled, not waiting for alloc cfg clear response\n",
2480 intf_id);
2481 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302482 } else {
2483 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 +05302484 intf_id, bcmos_strerror(err));
Girish Gowdra96461052019-11-22 20:13:59 +05302485 return err;
2486 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002487 } else if (direction == downstream) {
2488 bcmolt_tm_sched_cfg cfg;
2489 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002490
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002491 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2492 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302493 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002494 } else {
2495 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2496 return BCM_ERR_OK;
2497 }
Girish Gowdra96461052019-11-22 20:13:59 +05302498
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002499 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2500 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2501 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002502 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002503intf_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 +00002504 return err;
2505 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002506 }
2507
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002508 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d, tech_profile_id %d\n",
2509 direction.c_str(), sched_id, intf_id, onu_id, tech_profile_id);
2510 free_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002511 return BCM_ERR_OK;
2512}
2513
Girish Gowdra252f4972020-09-07 21:24:01 -07002514Status RemoveTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002515 uint32_t intf_id = traffic_scheds->intf_id();
2516 uint32_t onu_id = traffic_scheds->onu_id();
2517 uint32_t uni_id = traffic_scheds->uni_id();
2518 std::string direction;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002519 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002520 bcmos_errno err;
2521
2522 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002523 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002524
2525 direction = GetDirection(traffic_sched.direction());
2526 if (direction.compare("direction-not-supported") == 0)
2527 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2528
2529 int alloc_id = traffic_sched.alloc_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002530 int tech_profile_id = traffic_sched.tech_profile_id();
2531 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002532 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002533 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002534 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2535 }
2536 }
2537 return Status::OK;
2538}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002539
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002540bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2541 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002542 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002543 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2544 bcmolt_tm_qmp_key tm_qmp_key;
2545 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002546
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002547 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2548 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002549 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed tm queue mapping profile count is 16.\n");
2550 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002551 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002552
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002553 tm_qmp_key.id = tm_qmp_id;
2554 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2555 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2556 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002557
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002558 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2559 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2560 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002561 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2562 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002563
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002564 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002565 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002566 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2567 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002568 return err;
2569 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002570
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002571 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2572 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002573 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002574}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002575
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002576bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2577 bcmos_errno err;
2578 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2579 bcmolt_tm_qmp_key tm_qmp_key;
2580 tm_qmp_key.id = tm_qmp_id;
2581
2582 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2583 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2584 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002585 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2586 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002587 return err;
2588 }
2589
2590 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2591 tm_qmp_key.id);
2592 return BCM_ERR_OK;
2593}
2594
2595bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2596 bcmos_errno err;
2597
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002598 /* Create default queues on the given PON/NNI scheduler */
2599 for (int queue_id = 0; queue_id < NUMBER_OF_DEFAULT_INTERFACE_QUEUES; queue_id++) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002600 bcmolt_tm_queue_cfg tm_queue_cfg;
2601 bcmolt_tm_queue_key tm_queue_key = {};
2602 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2603 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002604 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2605 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2606 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002607
2608 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2609 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2610 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2611
2612 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2613 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002614 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", \
2615 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 +00002616 return err;
2617 }
2618
2619 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2620 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2621 }
2622 return BCM_ERR_OK;
2623}
2624
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002625bcmos_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 +00002626 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 +00002627 bcmos_errno err;
2628 bcmolt_tm_queue_cfg cfg;
2629 bcmolt_tm_queue_key key = { };
2630 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 +00002631gemport_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 +00002632
2633 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002634 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002635
2636 if (priority > 7) {
2637 return BCM_ERR_RANGE;
2638 }
2639
2640 /* FIXME: The upstream queues have to be created once only.
2641 The upstream queues on the NNI scheduler are shared by all subscribers.
2642 When the first scheduler comes in, the queues get created, and are re-used by all others.
2643 Also, these queues should be present until the last subscriber exits the system.
2644 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2645
2646 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2647 for each GEM in TECH PROFILE */
2648 key.id = queue_id_list[priority];
2649
2650 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2651 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2652 key.id = 0;
2653 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2654 }
2655 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2656 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2657 }
2658 else {
2659 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2660 }
2661
2662 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2663
2664 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2665 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
2666
2667 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2668 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002669 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002670sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, tech_profile_id %d, err = %s\n", \
2671 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 +00002672 return err;
2673 }
2674
Girish Gowdra252f4972020-09-07 21:24:01 -07002675 if (direction.compare(upstream) == 0) {
2676 Status st = install_gem_port(access_intf_id, onu_id, gemport_id);
2677 if (st.error_code() != grpc::StatusCode::ALREADY_EXISTS && st.error_code() != grpc::StatusCode::OK) {
2678 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);
2679 return BCM_ERR_INTERNAL;
2680 }
2681 }
2682
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002683 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 +00002684intf_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 +00002685 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002686}
2687
Girish Gowdra252f4972020-09-07 21:24:01 -07002688Status CreateTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002689 uint32_t intf_id = traffic_queues->intf_id();
2690 uint32_t onu_id = traffic_queues->onu_id();
2691 uint32_t uni_id = traffic_queues->uni_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002692 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002693 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002694 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002695 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002696 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 +00002697
2698 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2699 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2700 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2701 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002702 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002703
2704 direction = GetDirection(traffic_queue.direction());
2705 if (direction.compare("direction-not-supported") == 0)
2706 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2707
2708 queues_priority_q[i] = traffic_queue.priority();
2709 queues_pbit_map[i] = traffic_queue.pbit_map();
2710 }
2711
2712 std::vector<uint32_t> tmq_map_profile(8, 0);
2713 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2714 queues_priority_q, COUNT_OF(queues_priority_q));
2715 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002716 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002717
2718 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2719 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002720 err = CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2721 if (err != BCM_ERR_OK) {
2722 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2723 return bcm_to_grpc_err(err, "Failed to create tm queue mapping profile");
2724 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002725 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2726 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2727 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2728 }
2729 }
2730
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002731 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002732 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002733
2734 direction = GetDirection(traffic_queue.direction());
2735 if (direction.compare("direction-not-supported") == 0)
2736 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2737
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002738 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 +00002739
Girish Gowdruf26cf882019-05-01 23:47:58 -07002740 // If the queue exists already, lets not return failure and break the loop.
2741 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002742 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002743 return bcm_to_grpc_err(err, "Failed to create queue");
2744 }
2745 }
2746 return Status::OK;
2747}
2748
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002749bcmos_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 +00002750 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 +00002751 bcmolt_tm_queue_cfg cfg;
2752 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002753 bcmos_errno err;
2754
2755 if (direction == downstream) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002756 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2757 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 +00002758 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002759 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002760 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 -08002761 return BCM_ERR_OK;
2762 }
2763 } else {
Girish Gowdra4fd30672020-11-09 17:23:06 -08002764 // Gemports are bi-directional (except in multicast case). We create the gem port when we create the
2765 // upstream queue (see CreateQueue function) and it makes sense to delete them when remove the upstream queues.
2766 // For multicast case we do not manage the install/remove of gem port in agent application. It is managed by BAL.
2767 // Moreover it also makes sense to remove when upstream queue is getting removed because the upstream queue MUST exist always.
2768 // It is possible that the downstream queues are not created for a subscriber (for ex: upstream EAPoL trap flow only exists
2769 // but no other flow, and in this case only upstream scheduler and queues exist. We do not have a scenario where only downstream
2770 // subscriber flows exist but no upstream )
2771 remove_gem_port(access_intf_id, gemport_id);
2772
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002773 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2774 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002775 return BCM_ERR_OK;
2776 }
2777
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002778 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2779 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2780 // Reset the queue id to 0 when using fixed queue.
2781 key.id = 0;
2782 }
2783 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2784 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2785 }
2786 else {
2787 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2788 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002789
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002790 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2791 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002792 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002793 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, queue_id %d, sched_id %d, \
2794tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n",
2795 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 -08002796 return err;
2797 }
2798
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002799 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2800intf_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 -08002801
2802 return BCM_ERR_OK;
2803}
2804
Girish Gowdra252f4972020-09-07 21:24:01 -07002805Status RemoveTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002806 uint32_t intf_id = traffic_queues->intf_id();
2807 uint32_t onu_id = traffic_queues->onu_id();
2808 uint32_t uni_id = traffic_queues->uni_id();
2809 uint32_t port_no = traffic_queues->port_no();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002810 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002811 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002812 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002813 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002814 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 +00002815
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002816 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002817 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002818
2819 direction = GetDirection(traffic_queue.direction());
2820 if (direction.compare("direction-not-supported") == 0)
2821 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2822
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002823 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 -08002824 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002825 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002826 return bcm_to_grpc_err(err, "Failed to remove queue");
2827 }
Jonathan Davis70c21812018-07-19 15:32:10 -04002828 }
2829
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002830 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 +00002831 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002832 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002833
2834 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
2835 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002836 err = RemoveTrafficQueueMappingProfile(tm_qmp_id);
2837 if (err != BCM_ERR_OK) {
2838 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2839 return bcm_to_grpc_err(err, "Failed to remove tm queue mapping profile");
2840 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002841 }
2842 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002843 clear_qos_type(intf_id, onu_id, uni_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04002844 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04002845}
Jason Huangbf45ffb2019-10-30 17:29:02 +08002846
Girish Gowdra252f4972020-09-07 21:24:01 -07002847Status PerformGroupOperation_(const ::openolt::Group *group_cfg) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002848
2849 bcmos_errno err;
2850 bcmolt_group_key key = {};
2851 bcmolt_group_cfg grp_cfg_obj;
2852 bcmolt_group_members_update grp_mem_upd;
2853 bcmolt_members_update_command grp_mem_upd_cmd;
2854 bcmolt_group_member_info member_info = {};
2855 bcmolt_group_member_info_list_u8 members = {};
2856 bcmolt_intf_ref interface_ref = {};
2857 bcmolt_egress_qos egress_qos = {};
2858 bcmolt_tm_sched_ref tm_sched_ref = {};
2859 bcmolt_action a_val = {};
2860
2861 uint32_t group_id = group_cfg->group_id();
2862
2863 OPENOLT_LOG(INFO, openolt_log_id, "PerformGroupOperation request received for Group %d\n", group_id);
2864
2865 if (group_id >= 0) {
2866 key.id = group_id;
2867 }
2868 else {
2869 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
2870 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
2871 }
2872
2873 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2874 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
2875
2876 OPENOLT_LOG(INFO, openolt_log_id, "Checking if Group %d exists...\n",group_id);
2877
2878 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
2879 if (err != BCM_ERR_OK) {
2880 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
2881 return bcm_to_grpc_err(err, "Error in querying group");
2882 }
2883
2884 members.len = group_cfg->members_size();
2885
2886 // IMPORTANT: A member cannot be added to a group if the group type is not determined.
2887 // Group type is determined after a flow is assigned to it.
2888 // Therefore, a group must be created first, then a flow (with multicast type) must be assigned to it.
2889 // Only then we can add members to the group.
2890
2891 // if group does not exist, create it and return.
2892 if (grp_cfg_obj.data.state == BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
2893
2894 if (members.len != 0) {
2895 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);
2896 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Non-empty member list given for non-existent group");
2897 } else {
2898
2899 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2900 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, cookie, key.id);
2901
2902 /* Setting group actions and action parameters, if any.
2903 Only remove_outer_tag and translate_inner_tag actions and i_vid action parameter
2904 are supported for multicast groups in BAL 3.1.
2905 */
2906 const ::openolt::Action& action = group_cfg->action();
2907 const ::openolt::ActionCmd &cmd = action.cmd();
2908
2909 bcmolt_action_cmd_id cmd_bmask = BCMOLT_ACTION_CMD_ID_NONE;
2910 if (cmd.remove_outer_tag()) {
2911 OPENOLT_LOG(INFO, openolt_log_id, "Action remove_outer_tag applied to Group %d.\n", group_id);
2912 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
2913 }
2914
2915 if (cmd.translate_inner_tag()) {
2916 OPENOLT_LOG(INFO, openolt_log_id, "Action translate_inner_tag applied to Group %d.\n", group_id);
2917 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG);
2918 }
2919
2920 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, cmd_bmask);
2921
2922 if (action.i_vid()) {
2923 OPENOLT_LOG(INFO, openolt_log_id, "Setting action parameter i_vid=%d for Group %d.\n", action.i_vid(), group_id);
2924 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
2925 }
2926
2927 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, action, a_val);
2928
2929 // Create group
2930 err = bcmolt_cfg_set(dev_id, &(grp_cfg_obj.hdr));
2931
2932 if (BCM_ERR_OK != err) {
2933 BCM_LOG(ERROR, openolt_log_id, "Failed to create Group %d, err = %s (%d)\n", key.id, bcmos_strerror(err), err);
2934 return bcm_to_grpc_err(err, "Error in creating group");
2935 }
2936
2937 BCM_LOG(INFO, openolt_log_id, "Group %d has been created and configured with empty member list.\n", key.id);
2938 return Status::OK;
2939 }
2940 }
2941
2942 // The group already exists. Continue configuring it according to the update member command.
2943
2944 OPENOLT_LOG(INFO, openolt_log_id, "Configuring existing Group %d.\n",group_id);
2945
2946 // MEMBER LIST CONSTRUCTION
2947 // Note that members.len can be 0 here. if the group already exists and the command is SET then sending
2948 // empty list to the group is a legit operation and this actually empties the member list.
2949 members.arr = (bcmolt_group_member_info*)bcmos_calloc((members.len)*sizeof(bcmolt_group_member_info));
2950
2951 if (!members.arr) {
2952 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to allocate memory for group member list.\n");
2953 return grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "Memory exhausted during member list creation");
2954 }
2955
2956 /* SET GROUP MEMBERS UPDATE COMMAND */
Girish Gowdra252f4972020-09-07 21:24:01 -07002957 ::openolt::Group::GroupMembersCommand command = group_cfg->command();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002958 switch(command) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002959 case ::openolt::Group::SET_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002960 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_SET;
2961 OPENOLT_LOG(INFO, openolt_log_id, "Setting %d members for Group %d.\n", members.len, group_id);
2962 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07002963 case ::openolt::Group::ADD_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002964 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_ADD;
2965 OPENOLT_LOG(INFO, openolt_log_id, "Adding %d members to Group %d.\n", members.len, group_id);
2966 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07002967 case ::openolt::Group::REMOVE_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002968 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_REMOVE;
2969 OPENOLT_LOG(INFO, openolt_log_id, "Removing %d members from Group %d.\n", members.len, group_id);
2970 break;
2971 default :
2972 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid value %d for group member command.\n", command);
2973 bcmos_free(members.arr);
2974 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group member command");
2975 }
2976
2977 // SET MEMBERS LIST
2978 for (int i = 0; i < members.len; i++) {
2979
Girish Gowdra252f4972020-09-07 21:24:01 -07002980 if (command == ::openolt::Group::REMOVE_MEMBERS) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002981 OPENOLT_LOG(INFO, openolt_log_id, "Removing group member %d from group %d\n",i,key.id);
2982 } else {
2983 OPENOLT_LOG(INFO, openolt_log_id, "Adding group member %d to group %d\n",i,key.id);
2984 }
2985
Girish Gowdra252f4972020-09-07 21:24:01 -07002986 ::openolt::GroupMember *member = (::openolt::GroupMember *) &group_cfg->members()[i];
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002987
2988 // Set member interface type
Girish Gowdra252f4972020-09-07 21:24:01 -07002989 ::openolt::GroupMember::InterfaceType if_type = member->interface_type();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002990 switch(if_type){
Girish Gowdra252f4972020-09-07 21:24:01 -07002991 case ::openolt::GroupMember::PON :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002992 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_PON);
2993 OPENOLT_LOG(INFO, openolt_log_id, "Interface type PON is assigned to GroupMember %d\n",i);
2994 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07002995 case ::openolt::GroupMember::EPON_1G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002996 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_1_G);
2997 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_1G is assigned to GroupMember %d\n",i);
2998 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07002999 case ::openolt::GroupMember::EPON_10G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003000 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_10_G);
3001 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_10G is assigned to GroupMember %d\n",i);
3002 break;
3003 default :
3004 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid interface type value %d for GroupMember %d.\n",if_type,i);
3005 bcmos_free(members.arr);
3006 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface type for a group member");
3007 }
3008
3009 // Set member interface id
3010 if (member->interface_id() >= 0) {
3011 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_id, member->interface_id());
3012 OPENOLT_LOG(INFO, openolt_log_id, "Interface %d is assigned to GroupMember %d\n", member->interface_id(), i);
3013 } else {
3014 bcmos_free(members.arr);
3015 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface id for a group member");
3016 }
3017
3018 // Set member interface_ref
3019 BCMOLT_FIELD_SET(&member_info, group_member_info, intf, interface_ref);
3020
3021 // Set member gem_port_id. This must be a multicast gemport.
3022 if (member->gem_port_id() >= 0) {
3023 BCMOLT_FIELD_SET(&member_info, group_member_info, svc_port_id, member->gem_port_id());
3024 OPENOLT_LOG(INFO, openolt_log_id, "GEM Port %d is assigned to GroupMember %d\n", member->gem_port_id(), i);
3025 } else {
3026 bcmos_free(members.arr);
3027 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid gem port id for a group member");
3028 }
3029
3030 // Set member scheduler id and queue_id
3031 uint32_t tm_sched_id = get_default_tm_sched_id(member->interface_id(), downstream);
3032 OPENOLT_LOG(INFO, openolt_log_id, "Scheduler %d is assigned to GroupMember %d\n", tm_sched_id, i);
3033 BCMOLT_FIELD_SET(&tm_sched_ref, tm_sched_ref, id, tm_sched_id);
3034 BCMOLT_FIELD_SET(&egress_qos, egress_qos, tm_sched, tm_sched_ref);
3035
3036 // We assume that all multicast traffic destined to a PON port is using the same fixed queue.
3037 uint32_t tm_queue_id;
3038 if (member->priority() >= 0 && member->priority() < NUMBER_OF_DEFAULT_INTERFACE_QUEUES) {
3039 tm_queue_id = queue_id_list[member->priority()];
3040 OPENOLT_LOG(INFO, openolt_log_id, "Queue %d is assigned to GroupMember %d\n", tm_queue_id, i);
3041 BCMOLT_FIELD_SET(&egress_qos, egress_qos, type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
3042 BCMOLT_FIELD_SET(&egress_qos.u.fixed_queue, egress_qos_fixed_queue, queue_id, tm_queue_id);
3043 } else {
3044 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid fixed queue priority/ID %d for GroupMember %d\n", member->priority(), i);
3045 bcmos_free(members.arr);
3046 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid queue priority for a group member");
3047 }
3048
3049 BCMOLT_FIELD_SET(&member_info, group_member_info, egress_qos, egress_qos);
3050 BCMOLT_ARRAY_ELEM_SET(&(members), i, member_info);
3051 }
3052
3053 BCMOLT_OPER_INIT(&grp_mem_upd, group, members_update, key);
3054 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.members, members);
3055 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.command, grp_mem_upd_cmd);
3056
3057 err = bcmolt_oper_submit(dev_id, &(grp_mem_upd.hdr));
3058 bcmos_free(members.arr);
3059
3060 if (BCM_ERR_OK != err) {
3061 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);
3062 return bcm_to_grpc_err(err, "Failed to submit members update operation for the group");
3063 }
3064
3065 OPENOLT_LOG(INFO, openolt_log_id, "Successfully submitted members update operation for Group %d\n", key.id);
3066
3067 return Status::OK;
3068}
Burak Gurdageb4ca2e2020-06-15 07:48:26 +00003069
3070Status DeleteGroup_(uint32_t group_id) {
3071
3072 bcmos_errno err = BCM_ERR_OK;
3073 bcmolt_group_cfg grp_cfg_obj;
3074 bcmolt_group_key key = {};
3075
3076
3077 OPENOLT_LOG(INFO, openolt_log_id, "Delete request received for group %d\n", group_id);
3078
3079 if (group_id >= 0) {
3080 key.id = group_id;
3081 } else {
3082 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
3083 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
3084 }
3085
3086 /* init the BAL INIT API */
3087 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3088
3089 OPENOLT_LOG(DEBUG, openolt_log_id, "Checking if group %d exists...\n",group_id);
3090
3091 // CONFIGURE GROUP MEMBERS
3092 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
3093 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
3094
3095 if (err != BCM_ERR_OK) {
3096 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
3097 return bcm_to_grpc_err(err, "Error in querying group");
3098 }
3099
3100 if (grp_cfg_obj.data.state != BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
3101 OPENOLT_LOG(DEBUG, openolt_log_id, "Group %d exists. Will be deleted.\n",group_id);
3102 err = bcmolt_cfg_clear(dev_id, &(grp_cfg_obj.hdr));
3103 if (err != BCM_ERR_OK) {
3104 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d cannot be deleted err = %s (%d).\n", group_id, bcmos_strerror(err), err);
3105 return bcm_to_grpc_err(err, "Failed to delete group");;
3106 }
3107 } else {
3108 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d does not exist.\n", group_id);
3109 return Status(grpc::StatusCode::NOT_FOUND, "Group not found");
3110 }
3111
3112 OPENOLT_LOG(INFO, openolt_log_id, "Group %d has been deleted successfully.\n", group_id);
3113 return Status::OK;
Jason Huang1d9cfce2020-05-20 22:58:47 +08003114}
3115
Girish Gowdra252f4972020-09-07 21:24:01 -07003116Status GetLogicalOnuDistanceZero_(uint32_t intf_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003117 bcmos_errno err = BCM_ERR_OK;
3118 uint32_t mld = 0;
3119 double LD0;
3120
3121 err = getOnuMaxLogicalDistance(intf_id, &mld);
3122 if (err != BCM_ERR_OK) {
3123 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3124 }
3125
3126 LD0 = LOGICAL_DISTANCE(mld*1000, MINIMUM_ONU_RESPONSE_RANGING_TIME, ONU_BIT_TRANSMISSION_DELAY);
3127 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance zero is %f, (PON %d)\n", LD0, intf_id);
3128 response->set_intf_id(intf_id);
3129 response->set_logical_onu_distance_zero(LD0);
3130
3131 return Status::OK;
3132}
3133
Girish Gowdra252f4972020-09-07 21:24:01 -07003134Status GetLogicalOnuDistance_(uint32_t intf_id, uint32_t onu_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003135 bcmos_errno err = BCM_ERR_OK;
3136 bcmolt_itu_onu_params itu = {};
3137 bcmolt_onu_cfg onu_cfg;
3138 bcmolt_onu_key onu_key = {};
3139 uint32_t mld = 0;
3140 double LDi;
3141
3142 onu_key.pon_ni = intf_id;
3143 onu_key.onu_id = onu_id;
3144
3145 err = getOnuMaxLogicalDistance(intf_id, &mld);
3146 if (err != BCM_ERR_OK) {
3147 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3148 }
3149
3150 /* Initialize the API struct. */
3151 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
3152 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
3153 BCMOLT_FIELD_SET_PRESENT(&itu, itu_onu_params, ranging_time);
3154 BCMOLT_FIELD_SET(&onu_cfg.data, onu_cfg_data, itu, itu);
3155 #ifdef TEST_MODE
3156 // It is impossible to mock the setting of onu_cfg.data.onu_state because
3157 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
3158 // set the onu_cfg.data.onu_state. So a new stub function is created and address
3159 // of onu_cfg is passed. This is one-of case where we need to add test specific
3160 // code in production code.
3161 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
3162 #else
3163 /* Call API function. */
3164 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
3165 #endif
3166 if (err != BCM_ERR_OK) {
3167 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);
3168 return bcm_to_grpc_err(err, "Failed to retrieve ONU ranging time");
3169 }
3170
3171 if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_ACTIVE) {
3172 OPENOLT_LOG(ERROR, openolt_log_id, "ONU is not yet activated (PON %d, ONU id %d)\n", intf_id, onu_id);
3173 return bcm_to_grpc_err(BCM_ERR_PARM, "ONU is not yet activated\n");
3174 }
3175
3176 LDi = LOGICAL_DISTANCE(mld*1000, onu_cfg.data.itu.ranging_time, ONU_BIT_TRANSMISSION_DELAY);
3177 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance is %f, (PON %d, ONU id %d)\n", LDi, intf_id, onu_id);
3178 response->set_intf_id(intf_id);
3179 response->set_onu_id(onu_id);
3180 response->set_logical_onu_distance(LDi);
3181
3182 return Status::OK;
3183}
Burak Gurdag74e3ab82020-12-17 13:35:06 +00003184
3185Status GetOnuStatistics_(uint32_t intf_id, uint32_t onu_id, openolt::OnuStatistics* onu_stats) {
3186 bcmos_errno err;
3187
3188 err = get_onu_statistics((bcmolt_interface_id)intf_id, (bcmolt_onu_id)onu_id, onu_stats);
3189
3190 if (err != BCM_ERR_OK) {
3191 OPENOLT_LOG(ERROR, openolt_log_id, "retrieval of ONU statistics failed - PON ID = %u, ONU ID = %u, err = %d - %s", intf_id, onu_id, err, bcmos_strerror(err));
3192 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of ONU statistics failed");
3193 }
3194
3195 OPENOLT_LOG(INFO, openolt_log_id, "retrieved ONU statistics for PON ID = %d, ONU ID = %d\n", (int)intf_id, (int)onu_id);
3196 return Status::OK;
3197}
3198
3199Status GetGemPortStatistics_(uint32_t intf_id, uint32_t gemport_id, openolt::GemPortStatistics* gemport_stats) {
3200 bcmos_errno err;
3201
3202 err = get_gemport_statistics((bcmolt_interface_id)intf_id, (bcmolt_gem_port_id)gemport_id, gemport_stats);
3203
3204 if (err != BCM_ERR_OK) {
3205 OPENOLT_LOG(ERROR, openolt_log_id, "retrieval of GEMPORT statistics failed - PON ID = %u, ONU ID = %u, err = %d - %s", intf_id, gemport_id, err, bcmos_strerror(err));
3206 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of GEMPORT statistics failed");
3207 }
3208
3209 OPENOLT_LOG(INFO, openolt_log_id, "retrieved GEMPORT statistics for PON ID = %d, GEMPORT ID = %d\n", (int)intf_id, (int)gemport_id);
3210 return Status::OK;
3211}