blob: a2b0bcf0ff31be381fef9a54ec243de449087795 [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);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000345 OPENOLT_LOG(INFO, openolt_log_id, "Enable OLT - %s-%s\n", VENDOR_ID, MODEL_ID);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600346
Jason Huangbf45ffb2019-10-30 17:29:02 +0800347 //check BCM daemon is connected or not
348 Status status = check_connection();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000349 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800350 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000351 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800352 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000353 Status status = SubscribeIndication();
354 if (!status.ok()) {
355 OPENOLT_LOG(ERROR, openolt_log_id, "SubscribeIndication failed - %s : %s\n",
356 grpc_status_code_to_string(status.error_code()).c_str(),
357 status.error_message().c_str());
358 return status;
359 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800360
361 //check BAL state in initial stage
362 status = check_bal_ready();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000363 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800364 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000365 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800366 }
367
368 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000369 bcmos_errno err;
370 bcmolt_odid dev;
371 OPENOLT_LOG(INFO, openolt_log_id, "Enabling PON %d Devices ... \n", BCM_MAX_DEVS_PER_LINE_CARD);
372 for (dev = 0; dev < BCM_MAX_DEVS_PER_LINE_CARD; dev++) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400373 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000374 bcmolt_device_key dev_key = { };
375 dev_key.device_id = dev;
376 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
377 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
378 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
Jason Huangbf45ffb2019-10-30 17:29:02 +0800379 if (err == BCM_ERR_NOT_CONNECTED) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000380 bcmolt_device_key key = {.device_id = dev};
381 bcmolt_device_connect oper;
382 BCMOLT_OPER_INIT(&oper, device, connect, key);
383 if (MODEL_ID == "asfvolt16") {
384 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
385 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_XGS__2_X);
386 } else if (MODEL_ID == "asgvolt64") {
387 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
388 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
389 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
390 }
391 err = bcmolt_oper_submit(dev_id, &oper.hdr);
392 if (err) {
393 failed_enable_device_cnt ++;
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500394 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 +0000395 if (failed_enable_device_cnt == BCM_MAX_DEVS_PER_LINE_CARD) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500396 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 +0000397 return Status(grpc::StatusCode::INTERNAL, "Failed to activate all PON ports");
398 }
399 }
400 bcmos_usleep(200000);
401 }
402 else {
403 OPENOLT_LOG(WARNING, openolt_log_id, "PON deivce %d already connected\n", dev);
404 state.activate();
405 }
406 }
407 init_stats();
Shad Ansari627b5782018-08-13 22:49:32 +0000408 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000409 }
Shad Ansariedef2132018-08-10 22:14:50 +0000410
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000411 /* Start CLI */
412 OPENOLT_LOG(INFO, def_log_id, "Starting CLI\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400413 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000414 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400415}
416
417Status Disable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400418 //In the earlier implementation Disabling olt is done by disabling the NNI port associated with that.
419 //In inband scenario instead of using management interface to establish connection with adapter ,NNI interface will be used.
420 //Disabling NNI port on olt disable causes connection loss between adapter and agent.
421 //To overcome this disable is implemented by disabling all the PON ports
422 //associated with the device so as to support both in-band
423 //and out of band scenarios.
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400424
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400425 Status status;
426 int failedCount = 0;
427 for (int i = 0; i < NumPonIf_(); i++) {
428 status = DisablePonIf_(i);
429 if (!status.ok()) {
430 failedCount+=1;
431 BCM_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", i);
432 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400433 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400434 if (failedCount == 0) {
435 state.deactivate();
Girish Gowdra252f4972020-09-07 21:24:01 -0700436 ::openolt::Indication ind;
437 ::openolt::OltIndication* olt_ind = new ::openolt::OltIndication;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400438 olt_ind->set_oper_state("down");
439 ind.set_allocated_olt_ind(olt_ind);
440 BCM_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
441 oltIndQ.push(ind);
442 return Status::OK;
443 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000444 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400445 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to disable olt ,all the PON ports are still in enabled state");
446 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400447
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400448 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 -0400449}
450
451Status Reenable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400452 Status status;
453 int failedCount = 0;
454 for (int i = 0; i < NumPonIf_(); i++) {
455 status = EnablePonIf_(i);
456 if (!status.ok()) {
457 failedCount+=1;
458 BCM_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", i);
459 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400460 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000461 if (failedCount == 0) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400462 state.activate();
Girish Gowdra252f4972020-09-07 21:24:01 -0700463 ::openolt::Indication ind;
464 ::openolt::OltIndication* olt_ind = new ::openolt::OltIndication;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400465 olt_ind->set_oper_state("up");
466 ind.set_allocated_olt_ind(olt_ind);
467 BCM_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
468 oltIndQ.push(ind);
469 return Status::OK;
470 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000471 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400472 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to re-enable olt ,all the PON ports are still in disabled state");
473 }
474 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 +0000475}
476
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000477inline uint64_t get_flow_status(uint16_t flow_id, uint16_t flow_type, uint16_t data_id) {
478 bcmos_errno err;
479 bcmolt_flow_key flow_key;
480 bcmolt_flow_cfg flow_cfg;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400481
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000482 flow_key.flow_id = flow_id;
483 flow_key.flow_type = (bcmolt_flow_type)flow_type;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400484
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000485 BCMOLT_CFG_INIT(&flow_cfg, flow, flow_key);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400486
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000487 switch (data_id) {
488 case ONU_ID: //onu_id
489 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, onu_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500490 #ifdef TEST_MODE
491 // It is impossible to mock the setting of flow_cfg.data.state because
492 // the actual bcmolt_cfg_get passes the address of flow_cfg.hdr and we cannot
493 // set the flow_cfg.data. So a new stub function is created and address
494 // of flow_cfg is passed. This is one-of case where we need to add test specific
495 // code in production code.
496 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
497 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000498 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500499 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000500 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500501 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get onu_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000502 return err;
503 }
504 return flow_cfg.data.onu_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400505 case FLOW_TYPE:
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500506 #ifdef TEST_MODE
507 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
508 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000509 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500510 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000511 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500512 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get flow_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000513 return err;
514 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400515 return flow_cfg.key.flow_type;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000516 case SVC_PORT_ID: //svc_port_id
517 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, svc_port_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500518 #ifdef TEST_MODE
519 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
520 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000521 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500522 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000523 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500524 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 +0000525 return err;
526 }
527 return flow_cfg.data.svc_port_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400528 case PRIORITY:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000529 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, priority);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500530 #ifdef TEST_MODE
531 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
532 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000533 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500534 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000535 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500536 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get priority, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000537 return err;
538 }
539 return flow_cfg.data.priority;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400540 case COOKIE: //cookie
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000541 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, cookie);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500542 #ifdef TEST_MODE
543 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
544 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000545 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500546 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000547 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500548 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get cookie, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000549 return err;
550 }
551 return flow_cfg.data.cookie;
552 case INGRESS_INTF_TYPE: //ingress intf_type
553 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500554 #ifdef TEST_MODE
555 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
556 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000557 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500558 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000559 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500560 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 +0000561 return err;
562 }
563 return flow_cfg.data.ingress_intf.intf_type;
564 case EGRESS_INTF_TYPE: //egress intf_type
565 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500566 #ifdef TEST_MODE
567 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
568 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000569 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500570 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000571 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500572 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 +0000573 return err;
574 }
575 return flow_cfg.data.egress_intf.intf_type;
576 case INGRESS_INTF_ID: //ingress intf_id
577 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500578 #ifdef TEST_MODE
579 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
580 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000581 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500582 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000583 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500584 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 +0000585 return err;
586 }
587 return flow_cfg.data.ingress_intf.intf_id;
588 case EGRESS_INTF_ID: //egress intf_id
589 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500590 #ifdef TEST_MODE
591 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
592 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000593 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500594 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000595 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500596 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 +0000597 return err;
598 }
599 return flow_cfg.data.egress_intf.intf_id;
600 case CLASSIFIER_O_VID:
601 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500602 #ifdef TEST_MODE
603 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
604 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000605 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500606 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000607 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500608 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 +0000609 return err;
610 }
611 return flow_cfg.data.classifier.o_vid;
612 case CLASSIFIER_O_PBITS:
613 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500614 #ifdef TEST_MODE
615 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
616 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000617 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500618 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000619 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500620 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 +0000621 return err;
622 }
623 return flow_cfg.data.classifier.o_pbits;
624 case CLASSIFIER_I_VID:
625 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500626 #ifdef TEST_MODE
627 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
628 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000629 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500630 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000631 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500632 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 +0000633 return err;
634 }
635 return flow_cfg.data.classifier.i_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400636 case CLASSIFIER_I_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000637 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500638 #ifdef TEST_MODE
639 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
640 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000641 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500642 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000643 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500644 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 +0000645 return err;
646 }
647 return flow_cfg.data.classifier.i_pbits;
648 case CLASSIFIER_ETHER_TYPE:
649 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500650 #ifdef TEST_MODE
651 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
652 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000653 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500654 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000655 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500656 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 +0000657 return err;
658 }
659 return flow_cfg.data.classifier.ether_type;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400660 case CLASSIFIER_IP_PROTO:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000661 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500662 #ifdef TEST_MODE
663 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
664 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000665 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500666 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000667 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500668 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 +0000669 return err;
670 }
671 return flow_cfg.data.classifier.ip_proto;
672 case CLASSIFIER_SRC_PORT:
673 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500674 #ifdef TEST_MODE
675 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
676 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000677 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500678 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000679 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500680 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 +0000681 return err;
682 }
683 return flow_cfg.data.classifier.src_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400684 case CLASSIFIER_DST_PORT:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000685 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500686 #ifdef TEST_MODE
687 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
688 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000689 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500690 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000691 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500692 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 +0000693 return err;
694 }
695 return flow_cfg.data.classifier.dst_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400696 case CLASSIFIER_PKT_TAG_TYPE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000697 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500698 #ifdef TEST_MODE
699 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
700 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000701 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500702 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000703 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500704 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 +0000705 return err;
706 }
707 return flow_cfg.data.classifier.pkt_tag_type;
708 case EGRESS_QOS_TYPE:
709 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500710 #ifdef TEST_MODE
711 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
712 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000713 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500714 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000715 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500716 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 +0000717 return err;
718 }
719 return flow_cfg.data.egress_qos.type;
720 case EGRESS_QOS_QUEUE_ID:
721 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500722 #ifdef TEST_MODE
723 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
724 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000725 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500726 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000727 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500728 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 +0000729 return err;
730 }
731 switch (flow_cfg.data.egress_qos.type) {
732 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE:
733 return flow_cfg.data.egress_qos.u.fixed_queue.queue_id;
734 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE:
735 return flow_cfg.data.egress_qos.u.tc_to_queue.tc_to_queue_id;
736 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC:
737 return flow_cfg.data.egress_qos.u.pbit_to_tc.tc_to_queue_id;
738 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE:
739 return flow_cfg.data.egress_qos.u.priority_to_queue.tm_q_set_id;
740 case BCMOLT_EGRESS_QOS_TYPE_NONE:
741 default:
742 return -1;
743 }
744 case EGRESS_QOS_TM_SCHED_ID:
745 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500746 #ifdef TEST_MODE
747 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
748 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000749 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500750 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000751 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500752 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 +0000753 return err;
754 }
755 return flow_cfg.data.egress_qos.tm_sched.id;
756 case ACTION_CMDS_BITMASK:
757 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500758 #ifdef TEST_MODE
759 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
760 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000761 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500762 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000763 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500764 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 +0000765 return err;
766 }
767 return flow_cfg.data.action.cmds_bitmask;
768 case ACTION_O_VID:
769 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500770 #ifdef TEST_MODE
771 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
772 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000773 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500774 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000775 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500776 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 +0000777 return err;
778 }
779 return flow_cfg.data.action.o_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400780 case ACTION_O_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000781 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500782 #ifdef TEST_MODE
783 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
784 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000785 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500786 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000787 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500788 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 +0000789 return err;
790 }
791 return flow_cfg.data.action.o_pbits;
792 case ACTION_I_VID:
793 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500794 #ifdef TEST_MODE
795 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
796 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000797 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500798 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000799 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500800 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 +0000801 return err;
802 }
803 return flow_cfg.data.action.i_vid;
804 case ACTION_I_PBITS:
805 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500806 #ifdef TEST_MODE
807 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
808 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000809 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500810 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000811 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500812 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 +0000813 return err;
814 }
815 return flow_cfg.data.action.i_pbits;
816 case STATE:
817 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, state);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500818 #ifdef TEST_MODE
819 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
820 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000821 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500822 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000823 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500824 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get state, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000825 return err;
826 }
827 return flow_cfg.data.state;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000828 case GROUP_ID:
829 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, group_id);
830 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
831 if (err) {
832 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get group_id, err = %s\n",bcmos_strerror(err));
833 return err;
834 }
835 return flow_cfg.data.group_id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000836 default:
837 return BCM_ERR_INTERNAL;
838 }
839
840 return err;
841}
842
843Status EnablePonIf_(uint32_t intf_id) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400844 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000845 bcmolt_pon_interface_cfg interface_obj;
846 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
847 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
848 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530849 bcmolt_status los_status;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000850
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530851 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000852 if (err == BCM_ERR_OK) {
853 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800854 OPENOLT_LOG(WARNING, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000855 return Status::OK;
856 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400857 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000858 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
859 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
860 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
861 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.interval, 5000);
862 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.onu_post_discovery_mode,
Girish Gowdra24297032020-03-23 12:32:37 -0700863 BCMOLT_ONU_POST_DISCOVERY_MODE_NONE);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000864 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.los, true);
865 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.onu_alarms, true);
866 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.tiwi, true);
867 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.ack_timeout, true);
868 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.sfi, true);
869 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.loki, true);
Burak Gurdag5e587792020-05-06 14:58:02 +0000870
871 // On GPON, power level mode is not set to its default value (i.e. 0) as documented in Broadcom documentation.
872 // Instead, it is set to 2 which means -6 dbM attenuation. Therefore, we explicitly set it to the default value below.
873 if (board_technology == "GPON") {
874 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.pls_maximum_allocation_size, BCMOLT_PON_POWER_LEVEL_PLS_MAXIMUM_ALLOCATION_SIZE_DEFAULT);
875 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.mode, BCMOLT_PON_POWER_LEVEL_MODE_DEFAULT);
876 }
877
kesavandc1f2db92020-08-31 15:32:06 +0530878 //Enable AES Encryption
879 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.key_exchange, BCMOLT_CONTROL_STATE_ENABLE);
880 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.authentication, BCMOLT_CONTROL_STATE_ENABLE);
881 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.fail_due_to_authentication_failure, BCMOLT_CONTROL_STATE_ENABLE);
882
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000883 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
884 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
885
886 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
887 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500888 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 +0000889 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
890 }
891 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
892 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500893 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 +0000894 return bcm_to_grpc_err(err, "Failed to enable PON interface");
895 }
896 else {
897 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
898 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
899 CreateDefaultSched(intf_id, downstream);
900 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400901 }
902
903 return Status::OK;
904}
905
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500906Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000907 bcmos_errno err;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400908 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000909 bcmolt_device_key dev_key = { };
910 bcmolt_olt_cfg olt_cfg = { };
911 bcmolt_olt_key olt_key = { };
912 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
913 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500914
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000915 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
916 topo.topology_maps.arr = &topo_map[0];
917 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
918 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
919 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400920 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000921 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400922 #ifdef TEST_MODE
923 // It is impossible to mock the setting of olt_cfg.data.bal_state because
924 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
925 // set the olt_cfg.data.topology. So a new stub function is created and address
926 // of olt_cfg is passed. This is one-of case where we need to test add specific
927 // code in production code.
928 err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
929 #else
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000930 err = bcmolt_cfg_get_mult_retry(dev_id, &olt_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400931 #endif
932 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500933 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 +0000934 return bcm_to_grpc_err(err, "cfg: Failed to query OLT topology");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500935 }
936
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000937 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
938 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500939
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400940 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
941 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000942 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500943
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000944 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
945 num_of_nni_ports,
946 num_of_pon_ports,
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400947 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500948
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000949 uint32_t num_failed_cfg_gets = 0;
Jason Huang09b73ea2020-01-08 17:52:05 +0800950 static std::string openolt_version = firmware_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000951 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
952 dev_key.device_id = devid;
953 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
954 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
955 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
956 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000957 err = bcmolt_cfg_get_mult_retry(dev_id, &dev_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400958 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500959 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 +0000960 num_failed_cfg_gets++;
961 continue;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000962 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500963
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000964 std::string bal_version;
965 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
966 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
967 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
Jason Huang09b73ea2020-01-08 17:52:05 +0800968 firmware_version = "BAL." + bal_version + "__" + openolt_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000969
970 switch(dev_cfg.data.system_mode) {
971 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
972 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
973 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
974 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
975 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
976 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
977 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
978 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
979 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
980 case 20: board_technology = MIXED_TECH; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,MIXED_TECH); break;
981 }
982
983 switch(dev_cfg.data.chip_family) {
Jason Huang09b73ea2020-01-08 17:52:05 +0800984 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X: chip_family = "Maple"; break;
985 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X: chip_family = "Aspen"; break;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000986 }
987
Jason Huang09b73ea2020-01-08 17:52:05 +0800988 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s, family: %s, board_technology: %s\n",
989 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 +0000990
991 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500992 }
993
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000994 /* 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 +0000995 only the devices that retured success*/
996 if (num_failed_cfg_gets == BCM_MAX_DEVS_PER_LINE_CARD) {
997 OPENOLT_LOG(ERROR, openolt_log_id, "device: Query of all the devices failed\n");
998 return bcm_to_grpc_err(err, "device: All devices failed query");
999 }
1000
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001001 return Status::OK;
1002}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001003
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001004Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001005 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001006 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
1007 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
1008 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001009
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001010 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001011 if (err == BCM_ERR_OK) {
1012 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001013 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001014 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1015 CreateDefaultSched(intf_id, upstream);
1016 CreateDefaultQueue(intf_id, upstream);
1017 return Status::OK;
1018 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1019 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
1020 return Status::OK;
1021 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001022 }
1023
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001024 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
1025 if (set_state) {
1026 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1027 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1028 } else {
1029 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1030 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1031 }
1032 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
1033 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001034 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err = %s\n",
1035 (set_state)?"enable":"disable", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001036 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
1037 }
1038 else {
1039 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
1040 if (set_state) {
1041 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1042 CreateDefaultSched(intf_id, upstream);
1043 CreateDefaultQueue(intf_id, upstream);
1044 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001045 }
1046
1047 return Status::OK;
1048}
1049
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001050Status DisablePonIf_(uint32_t intf_id) {
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001051 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001052 bcmolt_pon_interface_cfg interface_obj;
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001053 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1054 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001055
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001056 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
1057 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1058 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_DISABLE);
1059
1060 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1061 if (err != BCM_ERR_OK) {
1062 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable discovery of onu, PON interface %d, err %d\n", intf_id, err);
1063 return bcm_to_grpc_err(err, "Failed to disable discovery of onu");
1064 }
1065
1066 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1067 operation, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1068
1069 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1070 if (err != BCM_ERR_OK) {
1071 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 -04001072 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001073 }
1074
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001075 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled PON interface: %d\n", intf_id);
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001076 return Status::OK;
1077}
1078
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001079Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
kesavandc1f2db92020-08-31 15:32:06 +05301080 const char *vendor_id, const char *vendor_specific, uint32_t pir, bool omcc_encryption_mode) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001081 bcmos_errno err = BCM_ERR_OK;
1082 bcmolt_onu_cfg onu_cfg;
1083 bcmolt_onu_key onu_key;
1084 bcmolt_serial_number serial_number; /**< ONU serial number */
1085 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001086
Girish Gowdra24297032020-03-23 12:32:37 -07001087 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1088 bcmolt_onu_state onu_state;
1089
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001090 onu_key.onu_id = onu_id;
1091 onu_key.pon_ni = intf_id;
1092 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1093 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Girish Gowdra24297032020-03-23 12:32:37 -07001094#ifdef TEST_MODE
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001095 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1096 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1097 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1098 // of onu_cfg is passed. This is one-of case where we need to add test specific
1099 // code in production code.
1100 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Girish Gowdra24297032020-03-23 12:32:37 -07001101#else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001102 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Girish Gowdra24297032020-03-23 12:32:37 -07001103#endif
1104 OPENOLT_LOG(INFO, openolt_log_id, "Activate ONU : old state = %d, current state = %d\n",
1105 onu_cfg.data.onu_old_state, onu_cfg.data.onu_state);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001106 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001107 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) {
1108 OPENOLT_LOG(INFO, openolt_log_id, "ONU is already in ACTIVE state, \
1109not processing this request for pon_intf=%d onu_id=%d\n", intf_id, onu_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001110 return Status::OK;
Girish Gowdra24297032020-03-23 12:32:37 -07001111 } else if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_NOT_CONFIGURED &&
1112 onu_cfg.data.onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1113 // We need the ONU to be in NOT_CONFIGURED or INACTIVE state to further process the request
1114 OPENOLT_LOG(ERROR, openolt_log_id, "ONU in an invalid state to process the request, \
1115state=%d pon_intf=%d onu_id=%d\n", onu_cfg.data.onu_state, intf_id, onu_id);
1116 return bcm_to_grpc_err(err, "Failed to activate ONU, invalid ONU state");
1117 }
1118 } else {
1119 // This should never happen. BAL GET should succeed for non-existant ONUs too. The state of such ONUs will be NOT_CONFIGURED
1120 OPENOLT_LOG(ERROR, openolt_log_id, "ONU state query failed pon_intf=%d onu_id=%d\n", intf_id, onu_id);
1121 return bcm_to_grpc_err(err, "onu get failed");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001122 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001123
Girish Gowdra24297032020-03-23 12:32:37 -07001124 // If the ONU is not configured at all we need to first configure it
1125 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_NOT_CONFIGURED) {
1126 OPENOLT_LOG(INFO, openolt_log_id, "Configuring ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001127vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Girish Gowdra24297032020-03-23 12:32:37 -07001128 vendor_specific_to_str(vendor_specific).c_str(), pir);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001129
Girish Gowdra24297032020-03-23 12:32:37 -07001130 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1131 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1132 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1133 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1134 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1135 /*set burst and data profiles to fec disabled*/
1136 if (board_technology == "XGS-PON") {
1137 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1138 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1139 } else if (board_technology == "GPON") {
1140 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1141 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1142 }
1143 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1144 if (err != BCM_ERR_OK) {
1145 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to configure ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
1146 return bcm_to_grpc_err(err, "Failed to configure ONU");
1147 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001148 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001149
kesavandc1f2db92020-08-31 15:32:06 +05301150 if (omcc_encryption_mode == true) {
1151 // set the encryption mode for omci port id
1152 bcmolt_itupon_gem_cfg gem_cfg;
1153 bcmolt_itupon_gem_key key = {};
1154 bcmolt_gem_port_configuration configuration = {};
1155 key.pon_ni = intf_id;
1156 key.gem_port_id = onu_id;
1157 bcmolt_control_state encryption_mode;
1158 encryption_mode = BCMOLT_CONTROL_STATE_ENABLE;
1159 BCMOLT_CFG_INIT(&gem_cfg, itupon_gem, key);
1160 BCMOLT_FIELD_SET(&gem_cfg.data, itupon_gem_cfg_data, encryption_mode, encryption_mode);
1161 err = bcmolt_cfg_set(dev_id, &gem_cfg.hdr);
1162 if(err != BCM_ERR_OK) {
1163 OPENOLT_LOG(ERROR, openolt_log_id, "failed to confiure omci gem_port encryption mode = %d\n", onu_id);
1164 return bcm_to_grpc_err(err, "Access_Control set ITU PON OMCI Gem port failed");
1165 }
1166 }
Girish Gowdra24297032020-03-23 12:32:37 -07001167 // Now that the ONU is configured, move the ONU to ACTIVE state
1168 memset(&onu_cfg, 0, sizeof(bcmolt_onu_cfg));
1169 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1170 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1171 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
1172 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
1173 onu_state, BCMOLT_ONU_OPERATION_ACTIVE);
1174 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001175 if (err != BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001176 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 +00001177 return bcm_to_grpc_err(err, "Failed to activate ONU");
1178 }
Girish Gowdra24297032020-03-23 12:32:37 -07001179 // ONU will eventually get activated after we have submitted the operation request. The adapter will receive an asynchronous
1180 // ONU_ACTIVATION_COMPLETED_INDICATION
1181
1182 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 +00001183
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001184 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001185}
1186
Jonathan Davis70c21812018-07-19 15:32:10 -04001187Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1188 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001189 bcmos_errno err = BCM_ERR_OK;
1190 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1191 bcmolt_onu_cfg onu_cfg;
1192 bcmolt_onu_key onu_key; /**< Object key. */
1193 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001194
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001195 onu_key.onu_id = onu_id;
1196 onu_key.pon_ni = intf_id;
1197 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1198 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001199 #ifdef TEST_MODE
1200 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1201 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1202 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1203 // of onu_cfg is passed. This is one-of case where we need to add test specific
1204 // code in production code.
1205 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001206 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001207 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001208 #endif
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301209 onu_state = onu_cfg.data.onu_state;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001210 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001211 switch (onu_state) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001212 case BCMOLT_ONU_STATE_ACTIVE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001213 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001214 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001215 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1216 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1217 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001218 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 +00001219 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1220 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301221 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 +00001222 break;
1223 }
Jonathan Davis70c21812018-07-19 15:32:10 -04001224 }
1225
1226 return Status::OK;
1227}
1228
1229Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001230 const char *vendor_id, const char *vendor_specific) {
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301231 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301232 bcmolt_onu_state onu_state;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001233
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001234 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 -05001235 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1236
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001237 // Need to deactivate before removing it (BAL rules)
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001238 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301239
1240 err = get_onu_status((bcmolt_interface)intf_id, onu_id, &onu_state);
1241 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001242 if (onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1243 OPENOLT_LOG(INFO, openolt_log_id, "waiting for onu deactivate complete response: intf_id=%d, onu_id=%d\n",
1244 intf_id, onu_id);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301245 err = wait_for_onu_deactivate_complete(intf_id, onu_id);
1246 if (err) {
1247 OPENOLT_LOG(ERROR, openolt_log_id, "failed to delete onu intf_id %d, onu_id %d\n",
1248 intf_id, onu_id);
1249 return bcm_to_grpc_err(err, "Failed to delete ONU");
1250 }
1251 }
Girish Gowdra24297032020-03-23 12:32:37 -07001252 else {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301253 OPENOLT_LOG(INFO, openolt_log_id, "Onu is Inactive, onu_id: %d, not waiting for onu deactivate complete response\n",
1254 intf_id);
1255 }
1256 }
1257 else {
1258 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch Onu status, onu_id = %d, intf_id = %d, err = %s\n",
1259 onu_id, intf_id, bcmos_strerror(err));
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301260 return bcm_to_grpc_err(err, "Failed to delete ONU");
1261 }
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001262
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001263 bcmolt_onu_cfg cfg_obj;
1264 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001265
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001266 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 -04001267 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001268
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001269 key.onu_id = onu_id;
1270 key.pon_ni = intf_id;
1271 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001272
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301273 err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001274 if (err != BCM_ERR_OK)
1275 {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001276 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 -04001277 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1278 }
1279
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301280 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 +00001281 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001282}
1283
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001284#define MAX_CHAR_LENGTH 20
1285#define MAX_OMCI_MSG_LENGTH 44
1286Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001287 bcmolt_bin_str buf = {};
1288 bcmolt_onu_cpu_packets omci_cpu_packets;
1289 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001290
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001291 key.pon_ni = intf_id;
1292 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001293
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001294 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1295 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1296 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001297
1298 // ???
1299 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1300 buf.len = MAX_OMCI_MSG_LENGTH;
1301 } else {
1302 buf.len = pkt.size()/2;
1303 }
1304
1305 /* Send the OMCI packet using the BAL remote proxy API */
1306 uint16_t idx1 = 0;
1307 uint16_t idx2 = 0;
1308 uint8_t arraySend[buf.len];
1309 char str1[MAX_CHAR_LENGTH];
1310 char str2[MAX_CHAR_LENGTH];
1311 memset(&arraySend, 0, buf.len);
1312
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001313 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1314 sprintf(str1,"%c", pkt[idx1]);
1315 sprintf(str2,"%c", pkt[++idx1]);
1316 strcat(str1,str2);
1317 arraySend[idx2] = strtol(str1, NULL, 16);
1318 }
1319
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001320 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1321 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001322
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001323 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1324 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1325 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001326
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001327 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001328 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001329 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 +00001330 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001331 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001332 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 -05001333 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001334 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001335 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001336
1337 return Status::OK;
1338}
1339
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001340Status 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 +00001341 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1342 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1343 bcmolt_bin_str buf = {};
1344 bcmolt_gem_port_id gem_port_id_array[1];
1345 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001346
Craig Lutgen967a1d02018-11-27 10:41:51 -06001347 if (port_no > 0) {
1348 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001349 if (gemport_id == 0) {
1350 bcmos_fastlock_lock(&data_lock);
1351 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1352 // Pick any flow that is mapped with the same port_no.
1353 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1354 if (it != port_to_flows.end() && !it->second.empty()) {
1355 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1356 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1357 if (fit != flowid_to_gemport.end()) {
1358 found = true;
1359 gemport_id = fit->second;
1360 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001361 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001362 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001363
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001364 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001365 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 -08001366 onu_id, port_no, intf_id);
1367 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1368 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001369 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 -08001370 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001371 }
1372
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001373 gem_port_id_array[0] = gemport_id;
1374 gem_port_list.len = 1;
1375 gem_port_list.arr = gem_port_id_array;
1376 buf.len = pkt.size();
1377 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1378 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1379
1380 /* init the API struct */
1381 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1382 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1383 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1384 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1385 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1386
1387 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1388 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1389
1390 /* call API */
1391 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001392 }
1393 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001394 //TODO: Port No is 0, it is coming sender requirement.
1395 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1396 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001397 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001398 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001399
1400 return Status::OK;
1401}
1402
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001403Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001404 bcmolt_flow_key key = {}; /* declare key */
1405 bcmolt_bin_str buffer = {};
1406 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001407
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001408 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
Girish Gowdra252f4972020-09-07 21:24:01 -07001409 bcmolt_flow_id flow_id = INVALID_FLOW_ID;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001410
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001411 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1412 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1413 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1414 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1415 key.flow_id = flow_id;
1416 else {
Jason Huang09b73ea2020-01-08 17:52:05 +08001417 if (flow_id_counters) {
1418 std::map<flow_pair, int>::iterator it;
1419 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1420 int flow_index = it->first.first;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001421 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1422 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1423 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1424 key.flow_id = flow_index;
1425 break;
1426 }
1427 }
1428 }
1429 else {
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001430 OPENOLT_LOG(ERROR, openolt_log_id, "no flow id found for uplink packetout\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001431 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1432 }
1433 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001434
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001435 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001436
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001437 /* Initialize the API struct. */
1438 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001439
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001440 buffer.len = pkt.size();
1441 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1442 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1443 if (buffer.arr == NULL) {
1444 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1445 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1446 }
1447 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1448
1449 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1450 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001451 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 -05001452 return bcm_to_grpc_err(BCM_ERR_SYSCALL_ERR, "Error sending packets via nni port");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001453 } else {
1454 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1455 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001456
1457 return Status::OK;
1458}
Girish Gowdra252f4972020-09-07 21:24:01 -07001459
1460Status FlowAddWrapper_(const ::openolt::Flow* request) {
1461
1462 int32_t access_intf_id = request->access_intf_id();
1463 int32_t onu_id = request->onu_id();
1464 int32_t uni_id = request->uni_id();
1465 uint32_t port_no = request->port_no();
1466 uint64_t voltha_flow_id = request->flow_id();
1467 uint64_t symmetric_voltha_flow_id = request->symmetric_flow_id();
1468 const std::string flow_type = request->flow_type();
1469 int32_t alloc_id = request->alloc_id();
1470 int32_t network_intf_id = request->network_intf_id();
1471 int32_t gemport_id = request->gemport_id();
1472 const ::openolt::Classifier& classifier = request->classifier();
1473 const ::openolt::Action& action = request->action();
1474 int32_t priority = request->priority();
1475 uint64_t cookie = request->cookie();
1476 int32_t group_id = request->group_id();
1477 uint32_t tech_profile_id = request->tech_profile_id();
1478 bool replicate_flow = request->replicate_flow();
1479 const google::protobuf::Map<unsigned int, unsigned int> &pbit_to_gemport = request->pbit_to_gemport();
1480 uint16_t flow_id;
1481
1482 // The intf_id variable defaults to access(PON) interface ID.
1483 // For trap-from-nni flow where access interface ID is not valid , change it to NNI interface ID
1484 // This intf_id identifies the pool from which we get the flow_id
1485 uint32_t intf_id = access_intf_id;
1486 if (onu_id < 1) {
1487 onu_id = 1;
1488 }
1489 if (access_intf_id < 0) {
1490 intf_id = network_intf_id;
1491 }
1492
1493 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)
1494 // This is the case of voltha_flow_id (not symmetric_voltha_flow_id)
1495 if (is_voltha_flow_installed(voltha_flow_id)) {
1496 OPENOLT_LOG(INFO, openolt_log_id, "voltha_flow_id=%lu, already installed\n", voltha_flow_id);
1497 return ::Status(grpc::StatusCode::ALREADY_EXISTS, "voltha-flow-already-installed");
1498 }
1499
1500 // Trap-to-host voltha flows need not be replicated as they are installed as ACLs, not BAL flows.
1501 if (action.cmd().trap_to_host()) {
1502 replicate_flow = false;
1503 }
1504
1505 // This is the case of symmetric_voltha_flow_id
1506 // If symmetric_voltha_flow_id is available and valid in the Flow message,
1507 // check if it is installed, and use the corresponding device_flow_id
1508 if (symmetric_voltha_flow_id > 0 && is_voltha_flow_installed(symmetric_voltha_flow_id)) { // symmetric flow found
1509 OPENOLT_LOG(INFO, openolt_log_id, "symmetric flow and the symmetric flow is installed\n");
1510 const device_flow_params *dev_fl_symm_params;
1511 dev_fl_symm_params = get_device_flow_params(symmetric_voltha_flow_id);
1512 if (dev_fl_symm_params == NULL) {
1513 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)
1514 return ::Status(grpc::StatusCode::INTERNAL, "symmetric-flow-details-not-found");
1515 }
1516
1517 if (!replicate_flow) { // No flow replication
1518 flow_id = dev_fl_symm_params[0].flow_id;
1519 gemport_id = dev_fl_symm_params[0].gemport_id; // overwrite the gemport with symmetric flow gemport
1520 // Should be same as what is coming in this request.
1521 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1522 cl.set_o_pbits(dev_fl_symm_params[0].pbit);
1523 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1524 flow_type, alloc_id, network_intf_id, gemport_id, cl,
1525 action, priority, cookie, group_id, tech_profile_id);
1526 if (st.error_code() == grpc::StatusCode::OK) {
1527 device_flow dev_fl;
1528 dev_fl.is_flow_replicated = false;
1529 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1530 dev_fl.voltha_flow_id = voltha_flow_id;
1531 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params));
1532 // update voltha flow to cache
1533 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1534 }
1535 return st;
1536 } else { // Flow to be replicated
1537 OPENOLT_LOG(INFO, openolt_log_id,"symmetric flow and replication is needed\n");
1538 for (uint8_t i=0; i<NUMBER_OF_REPLICATED_FLOWS; i++) {
1539 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1540 flow_id = dev_fl_symm_params[i].flow_id;
1541 gemport_id = dev_fl_symm_params[i].gemport_id;
1542 cl.set_o_pbits(dev_fl_symm_params[i].pbit);
1543 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1544 flow_type, alloc_id, network_intf_id, gemport_id, classifier,
1545 action, priority, cookie, group_id, tech_profile_id);
1546 if (st.error_code() != grpc::StatusCode::OK && st.error_code() != grpc::StatusCode::ALREADY_EXISTS) {
1547 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);
1548 // On failure remove any successfully replicated flows installed so far for the voltha_flow_id
1549 if (i > 0) {
1550 for (int8_t j = i-1; j >= 0; j--) {
1551 flow_id = dev_fl_symm_params[j].flow_id;
1552 FlowRemove_(flow_id, flow_type);
1553 }
1554 }
1555 return st;
1556 }
1557 }
1558 device_flow dev_fl;
1559 dev_fl.is_flow_replicated = true;
1560 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1561 dev_fl.voltha_flow_id = voltha_flow_id;
1562 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params)*NUMBER_OF_REPLICATED_FLOWS);
1563 // update voltha flow to cache
1564 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1565 }
1566 } else { // No symmetric flow found
1567 if (!replicate_flow) { // No flow replication
1568 OPENOLT_LOG(INFO, openolt_log_id, "not a symmetric flow and replication is not needed\n");
1569 flow_id = get_flow_id();
1570 if (flow_id == INVALID_FLOW_ID) {
1571 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocated flow id for voltha-flow-id=%lu\n", voltha_flow_id);
1572 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1573 }
1574 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1575 flow_type, alloc_id, network_intf_id, gemport_id, classifier,
1576 action, priority, cookie, group_id, tech_profile_id);
1577 if (st.error_code() == grpc::StatusCode::OK) {
1578 device_flow dev_fl;
1579 dev_fl.is_flow_replicated = false;
1580 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // Invalid
1581 dev_fl.voltha_flow_id = voltha_flow_id;
1582 dev_fl.params[0].flow_id = flow_id;
1583 dev_fl.params[0].gemport_id = gemport_id;
1584 dev_fl.params[0].pbit = classifier.o_pbits();
1585 // update voltha flow to cache
1586 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1587 } else {
1588 // Free the flow id on failure
1589 free_flow_id(flow_id);
1590 }
1591 return st;
1592 } else { // Flow to be replicated
1593 OPENOLT_LOG(INFO, openolt_log_id,"not a symmetric flow and replication is needed\n");
1594 if (pbit_to_gemport.size() != NUMBER_OF_PBITS) {
1595 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pbit-to-gemport map size=%lu", pbit_to_gemport.size())
1596 return ::Status(grpc::StatusCode::OUT_OF_RANGE, "pbit-to-gemport-map-len-invalid-for-flow-replication");
1597 }
1598 uint16_t flow_ids[NUMBER_OF_REPLICATED_FLOWS];
1599 device_flow dev_fl;
1600 if (get_flow_ids(NUMBER_OF_REPLICATED_FLOWS, flow_ids)) {
1601 uint8_t cnt = 0;
1602 dev_fl.is_flow_replicated = true;
1603 dev_fl.voltha_flow_id = voltha_flow_id;
1604 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // invalid
1605 for (google::protobuf::Map<unsigned int, unsigned int>::const_iterator it=pbit_to_gemport.begin(); it!=pbit_to_gemport.end(); it++) {
1606 dev_fl.params[cnt].flow_id = flow_ids[cnt];
1607 dev_fl.params[cnt].pbit = it->first;
1608 dev_fl.params[cnt].gemport_id = it->second;
1609
1610 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1611 flow_id = dev_fl.params[cnt].flow_id;
1612 gemport_id = dev_fl.params[cnt].gemport_id;
1613 cl.set_o_pbits(dev_fl.params[cnt].pbit);
1614 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1615 flow_type, alloc_id, network_intf_id, gemport_id, cl,
1616 action, priority, cookie, group_id, tech_profile_id);
1617 if (st.error_code() != grpc::StatusCode::OK) {
1618 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);
1619 // Remove any successfully replicated flows installed so far for the voltha_flow_id
1620 if (cnt > 0) {
1621 for (int8_t j = cnt-1; j >= 0; j--) {
1622 flow_id = dev_fl.params[j].flow_id;
1623 FlowRemove_(flow_id, flow_type);
1624 }
1625 }
1626 // Free up all the flow IDs on failure
1627 free_flow_ids(NUMBER_OF_REPLICATED_FLOWS, flow_ids);
1628 return st;
1629 }
1630 cnt++;
1631 }
1632 // On successful flow replication update voltha-flow-id to device-flow map to cache
1633 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1634 } else {
1635 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocate flow ids for replication voltha-flow-id=%lu\n", voltha_flow_id);
1636 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1637 }
1638 }
1639 }
1640
1641 return Status::OK;
1642}
1643
1644
Craig Lutgen967a1d02018-11-27 10:41:51 -06001645Status 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 +00001646 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001647 int32_t alloc_id, int32_t network_intf_id,
1648 int32_t gemport_id, const ::openolt::Classifier& classifier,
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001649 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00001650 int32_t group_id, uint32_t tech_profile_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001651 bcmolt_flow_cfg cfg;
1652 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001653 int32_t o_vid = -1;
1654 bool single_tag = false;
1655 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001656 bcmolt_classifier c_val = { };
1657 bcmolt_action a_val = { };
1658 bcmolt_tm_queue_ref tm_val = { };
1659 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05001660 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001661
Jason Huang09b73ea2020-01-08 17:52:05 +08001662 OPENOLT_LOG(INFO, openolt_log_id, "flow add received for flow_id=%u, flow_type=%s\n", flow_id, flow_type.c_str());
1663
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001664 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001665 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001666 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001667 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001668 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001669 } else if (flow_type.compare(multicast) == 0) {
1670 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001671 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001672 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001673 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001674 }
1675
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001676 BCMOLT_CFG_INIT(&cfg, flow, key);
1677 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001678
Jason Huang09b73ea2020-01-08 17:52:05 +08001679 if (action.cmd().trap_to_host()) {
1680 Status resp = handle_acl_rule_install(onu_id, flow_id, flow_type, access_intf_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001681 network_intf_id, classifier);
Jason Huang09b73ea2020-01-08 17:52:05 +08001682 return resp;
1683 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001684
1685 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1686
1687 if (access_intf_id >= 0 && network_intf_id >= 0) {
1688 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1689 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1690 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08001691 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1692 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001693 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1694 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1695 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1696 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1697 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001698 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001699 } else {
1700 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
1701 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001702 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001703
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001704 if (onu_id >= 0) {
1705 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
1706 }
1707 if (gemport_id >= 0) {
1708 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
1709 }
1710 if (gemport_id >= 0 && port_no != 0) {
1711 bcmos_fastlock_lock(&data_lock);
1712 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
1713 port_to_flows[port_no].insert(key.flow_id);
1714 flowid_to_gemport[key.flow_id] = gemport_id;
1715 }
1716 else
1717 {
1718 flowid_to_port[key.flow_id] = port_no;
1719 }
1720 bcmos_fastlock_unlock(&data_lock, 0);
1721 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001722
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001723 if (priority_value >= 0) {
1724 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
1725 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301726
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001727 } else { // MULTICAST FLOW
1728 if (group_id >= 0) {
1729 BCMOLT_MSG_FIELD_SET(&cfg, group_id, group_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001730 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001731 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1732 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001733 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001734
1735 {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001736 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001737 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001738 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
1739 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001740 }
1741
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001742 if (classifier.dst_mac().size() > 0) {
1743 bcmos_mac_address d_mac = {};
1744 bcmos_mac_address_init(&d_mac);
1745 memcpy(d_mac.u8, classifier.dst_mac().data(), sizeof(d_mac.u8));
1746 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_mac %02x:%02x:%02x:%02x:%02x:%02x\n", d_mac.u8[0],
1747 d_mac.u8[1], d_mac.u8[2], d_mac.u8[3], d_mac.u8[4], d_mac.u8[5]);
1748 BCMOLT_FIELD_SET(&c_val, classifier, dst_mac, d_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001749 }
1750
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001751 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001752 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001753 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001754 }
1755 */
1756
1757 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001758 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
1759 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001760 }
1761
1762 /*
1763 if (classifier.dst_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001764 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_ip, classifier.dst_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001765 }
1766
1767 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001768 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001769 }
1770 */
1771
1772 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001773 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
1774 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001775 }
1776
1777 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001778 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
1779 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001780 }
1781
1782 if (!classifier.pkt_tag_type().empty()) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001783 if (classifier.o_vid()) {
1784 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
1785 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
1786 }
1787
1788 if (classifier.i_vid()) {
1789 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
1790 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
1791 }
1792
1793 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
1794 if (classifier.pkt_tag_type().compare("untagged") == 0) {
1795 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
1796 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
1797 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
1798 single_tag = true;
1799
1800 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301801 // OpenOlt adapter will send 0xFF in case of no pbit classification
1802 // If it is any other value (0 to 7), it is for outer pbit classification.
1803 // OpenFlow protocol does not provide inner pbit classification (in case of double tagged packets),
1804 // and VOLTHA has not used any workaround to solve this problem (for ex: use metadata field).
1805 // Also there exists no use case for i-pbit classification, so we can safely ignore this for now.
1806 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001807 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301808 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001809 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
1810 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001811
Jason Huang09b73ea2020-01-08 17:52:05 +08001812 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301813 // Same comments as in case of "single_tag" packets.
1814 // 0xFF means no pbit classification, otherwise a valid PCP (0 to 7).
1815 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001816 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301817 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001818 }
1819 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001820 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001821 }
1822
Jason Huang09b73ea2020-01-08 17:52:05 +08001823 const ::openolt::ActionCmd& cmd = action.cmd();
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001824
Jason Huang09b73ea2020-01-08 17:52:05 +08001825 if (cmd.add_outer_tag()) {
1826 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
1827 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001828 }
1829
Jason Huang09b73ea2020-01-08 17:52:05 +08001830 if (cmd.remove_outer_tag()) {
1831 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
1832 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
1833 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301834
Jason Huang09b73ea2020-01-08 17:52:05 +08001835 if (action.o_vid()) {
1836 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
1837 o_vid = action.o_vid();
1838 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
1839 }
1840
1841 if (action.o_pbits()) {
1842 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
1843 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
1844 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301845
Jason Huang09b73ea2020-01-08 17:52:05 +08001846 if (action.i_vid()) {
1847 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
1848 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
1849 }
1850
1851 if (action.i_pbits()) {
1852 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
1853 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
1854 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301855
Jason Huang09b73ea2020-01-08 17:52:05 +08001856 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
1857
Shad Ansari39739bc2018-09-13 21:38:37 +00001858 if ((access_intf_id >= 0) && (onu_id >= 0)) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001859 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
1860 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00001861 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 +00001862
Jason Huang09b73ea2020-01-08 17:52:05 +08001863 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1864 // Queue 0 on DS subscriber scheduler
1865 tm_val.queue_id = 0;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001866
Jason Huang09b73ea2020-01-08 17:52:05 +08001867 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1868 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1869 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001870
Jason Huang09b73ea2020-01-08 17:52:05 +08001871 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1872 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1873 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001874
Jason Huang09b73ea2020-01-08 17:52:05 +08001875 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1876 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
1877 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 +00001878
Jason Huang09b73ea2020-01-08 17:52:05 +08001879 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1880 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1881 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1882 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 +00001883
Jason Huang09b73ea2020-01-08 17:52:05 +08001884 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
1885 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1886 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1887 }
1888 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
1889 // NNI Scheduler ID
1890 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1891 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1892 // Queue 0 on NNI scheduler
1893 tm_val.queue_id = 0;
1894 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1895 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1896 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001897
Jason Huang09b73ea2020-01-08 17:52:05 +08001898 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 +00001899 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1900 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1901
Jason Huang09b73ea2020-01-08 17:52:05 +08001902 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1903 /* Fetch TM QMP ID mapped to US NNI scheduler */
1904 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
1905 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1906 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1907 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1908 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 +00001909
Jason Huang09b73ea2020-01-08 17:52:05 +08001910 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 +00001911 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1912 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001913 }
Shad Ansari39739bc2018-09-13 21:38:37 +00001914 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301915 } else {
1916 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1917 tm_val.queue_id = 0;
1918
1919 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
1920 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1921 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
1922
1923 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1924 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
1925 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00001926 }
1927
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001928 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001929
Girish Gowdra252f4972020-09-07 21:24:01 -07001930#ifndef SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001931 // BAL 3.1 supports statistics only for unicast flows.
1932 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1933 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
1934 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001935#endif // SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001936
Girish Gowdra252f4972020-09-07 21:24:01 -07001937#ifndef SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001938#ifdef FLOW_CHECKER
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001939 //Flow Checker, To avoid duplicate flow.
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001940 if (flow_id_counters != 0) {
1941 bool b_duplicate_flow = false;
Jason Huang09b73ea2020-01-08 17:52:05 +08001942 std::map<flow_pair, int>::iterator it;
1943
1944 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1945 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(it->first.first, it->first.second, ONU_ID)) && \
1946 (key.flow_type == it->first.second) && \
1947 (cfg.data.svc_port_id == get_flow_status(it->first.first, it->first.second, SVC_PORT_ID)) && \
1948 (cfg.data.priority == get_flow_status(it->first.first, it->first.second, PRIORITY)) && \
1949 (cfg.data.cookie == get_flow_status(it->first.first, it->first.second, COOKIE)) && \
1950 (cfg.data.ingress_intf.intf_type == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_TYPE)) && \
1951 (cfg.data.ingress_intf.intf_id == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_ID)) && \
1952 (cfg.data.egress_intf.intf_type == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_TYPE)) && \
1953 (cfg.data.egress_intf.intf_id == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_ID)) && \
1954 (c_val.o_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_VID)) && \
1955 (c_val.o_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_PBITS)) && \
1956 (c_val.i_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_VID)) && \
1957 (c_val.i_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_PBITS)) && \
1958 (c_val.ether_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_ETHER_TYPE)) && \
1959 (c_val.ip_proto == get_flow_status(it->first.first, it->first.second, CLASSIFIER_IP_PROTO)) && \
1960 (c_val.src_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_SRC_PORT)) && \
1961 (c_val.dst_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_DST_PORT)) && \
1962 (c_val.pkt_tag_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_PKT_TAG_TYPE)) && \
1963 (cfg.data.egress_qos.type == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TYPE)) && \
1964 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_QUEUE_ID)) && \
1965 (cfg.data.egress_qos.tm_sched.id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TM_SCHED_ID)) && \
1966 (a_val.cmds_bitmask == get_flow_status(it->first.first, it->first.second, ACTION_CMDS_BITMASK)) && \
1967 (a_val.o_vid == get_flow_status(it->first.first, it->first.second, ACTION_O_VID)) && \
1968 (a_val.i_vid == get_flow_status(it->first.first, it->first.second, ACTION_I_VID)) && \
1969 (a_val.o_pbits == get_flow_status(it->first.first, it->first.second, ACTION_O_PBITS)) && \
1970 (a_val.i_pbits == get_flow_status(it->first.first, it->first.second, ACTION_I_PBITS)) && \
1971 (cfg.data.state == get_flow_status(it->first.first, it->first.second, STATE)) && \
1972 (cfg.data.group_id == get_flow_status(it->first.first, it->first.second, GROUP_ID));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001973#ifdef SHOW_FLOW_PARAM
1974 // Flow Parameter
1975 FLOW_PARAM_LOG();
1976#endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001977 if (b_duplicate_flow) {
1978 FLOW_LOG(WARNING, "Flow duplicate", 0);
1979 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
1980 }
1981 }
1982 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001983#endif // FLOW_CHECKER
1984#endif // SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001985
1986 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
1987 if (err) {
1988 FLOW_LOG(ERROR, "Flow add failed", err);
1989 return bcm_to_grpc_err(err, "flow add failed");
1990 } else {
1991 FLOW_LOG(INFO, "Flow add ok", err);
1992 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08001993 flow_map[std::pair<int, int>(key.flow_id,key.flow_type)] = flow_map.size();
1994 flow_id_counters = flow_map.size();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001995 bcmos_fastlock_unlock(&data_lock, 0);
Girish Gowdra252f4972020-09-07 21:24:01 -07001996
1997 }
1998 return Status::OK;
1999}
2000
2001Status FlowRemoveWrapper_(const ::openolt::Flow* request) {
2002 const std::string flow_type = request->flow_type();
2003 uint64_t voltha_flow_id = request->flow_id();
2004 Status st;
2005
2006 // If Voltha flow is not installed, return fail
2007 if (! is_voltha_flow_installed(voltha_flow_id)) {
2008 OPENOLT_LOG(ERROR, openolt_log_id, "voltha_flow_id=%lu not found\n", voltha_flow_id);
2009 return ::Status(grpc::StatusCode::NOT_FOUND, "voltha-flow-not-found");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002010 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04002011
Girish Gowdra252f4972020-09-07 21:24:01 -07002012 const device_flow *dev_fl = get_device_flow(voltha_flow_id);
2013 if (dev_fl == NULL) {
2014 OPENOLT_LOG(ERROR, openolt_log_id, "device flow for voltha_flow_id=%lu in the cache is NULL\n", voltha_flow_id);
2015 return ::Status(grpc::StatusCode::INTERNAL, "device-flow-null-in-cache");
2016 }
2017 if (dev_fl->is_flow_replicated) {
2018 // Note: Here we are ignoring FlowRemove failures
2019 for (int i=0; i<NUMBER_OF_REPLICATED_FLOWS; i++) {
2020 st = FlowRemove_(dev_fl->params[i].flow_id, flow_type);
2021 if (st.error_code() == grpc::StatusCode::OK) {
2022 free_flow_id(dev_fl->params[i].flow_id);
2023 }
2024 }
2025 } else {
2026 // Note: Here we are ignoring FlowRemove failures
2027 st = FlowRemove_(dev_fl->params[0].flow_id, flow_type);
2028 if (st.error_code() == grpc::StatusCode::OK) {
2029 free_flow_id(dev_fl->params[0].flow_id);
2030 }
2031 }
2032 // remove the flow from cache on voltha flow removal
2033 remove_voltha_flow_from_cache(voltha_flow_id);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002034 return Status::OK;
2035}
2036
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002037Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
2038
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002039 bcmolt_flow_cfg cfg;
2040 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002041
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002042 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002043 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002044 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002045 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002046 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002047 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002048 } else if(flow_type.compare(multicast) == 0) {
2049 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002050 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002051 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002052 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
2053 }
2054
Jason Huang09b73ea2020-01-08 17:52:05 +08002055 OPENOLT_LOG(INFO, openolt_log_id, "flow remove received for flow_id=%u, flow_type=%s\n",
2056 flow_id, flow_type.c_str());
2057
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002058 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002059 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
2060 int32_t gemport_id = -1;
2061 int32_t intf_id = -1;
2062 int16_t acl_id = -1;
2063 if (flow_to_acl_map.count(fl_id_fl_dir) > 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002064
2065 acl_id_intf_id ac_id_if_id = flow_to_acl_map[fl_id_fl_dir];
2066 acl_id = std::get<0>(ac_id_if_id);
2067 intf_id = std::get<1>(ac_id_if_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002068 // cleanup acl only if it is a valid acl. If not valid acl, it may be datapath flow.
2069 if (acl_id >= 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002070 Status resp = handle_acl_rule_cleanup(acl_id, intf_id, flow_type);
Jason Huang09b73ea2020-01-08 17:52:05 +08002071 bcmos_fastlock_unlock(&data_lock, 0);
2072 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);
2075 } else {
2076 OPENOLT_LOG(ERROR, openolt_log_id, "acl remove error for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2077 }
2078 return resp;
2079 }
2080 }
2081
Craig Lutgen967a1d02018-11-27 10:41:51 -06002082 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002083 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002084 flowid_to_gemport.erase(key.flow_id);
2085 port_to_flows[port_no].erase(key.flow_id);
2086 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
2087 }
2088 else
2089 {
2090 flowid_to_port.erase(key.flow_id);
2091 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002092 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002093
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002094 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002095
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002096 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002097 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002098 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 -04002099 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
2100 }
2101
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002102 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002103 if (flow_id_counters != 0) {
2104 std::map<flow_pair, int>::iterator it;
2105 for(it = flow_map.begin(); it != flow_map.end(); it++) {
2106 if (it->first.first == flow_id && it->first.second == key.flow_type) {
2107 flow_id_counters -= 1;
2108 flow_map.erase(it);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002109 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002110 }
2111 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002112 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
2113
Jason Huang09b73ea2020-01-08 17:52:05 +08002114 flow_to_acl_map.erase(fl_id_fl_dir);
2115
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002116 bcmos_fastlock_unlock(&data_lock, 0);
2117
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002118 return Status::OK;
2119}
2120
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002121bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
2122 bcmos_errno err;
2123 bcmolt_tm_sched_cfg tm_sched_cfg;
2124 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2125 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
2126
Jason Huangbf45ffb2019-10-30 17:29:02 +08002127 //check TM scheduler has configured or not
2128 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2129 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002130 #ifdef TEST_MODE
2131 // It is impossible to mock the setting of tm_sched_cfg.data.state because
2132 // the actual bcmolt_cfg_get passes the address of tm_sched_cfg.hdr and we cannot
2133 // set the tm_sched_cfg.data.state. So a new stub function is created and address
2134 // of tm_sched_cfg is passed. This is one-of case where we need to add test specific
2135 // code in production code.
2136 err = bcmolt_cfg_get__tm_sched_stub(dev_id, &tm_sched_cfg);
2137 #else
Jason Huangbf45ffb2019-10-30 17:29:02 +08002138 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002139 #endif
Jason Huangbf45ffb2019-10-30 17:29:02 +08002140 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002141 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 +08002142 return err;
2143 }
2144 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
2145 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
2146 return BCM_ERR_OK;
2147 }
2148
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002149 // bcmbal_tm_sched_owner
2150 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2151
2152 /**< The output of the tm_sched object instance */
2153 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
2154
2155 if (direction.compare(upstream) == 0) {
2156 // In upstream it is NNI scheduler
2157 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
2158 } else if (direction.compare(downstream) == 0) {
2159 // In downstream it is PON scheduler
2160 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2161 }
2162
2163 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2164
2165 // bcmbal_tm_sched_type
2166 // set the deafult policy to strict priority
2167 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2168
2169 // num_priorities: Max number of strict priority scheduling elements
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002170 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, NUM_OF_PRIORITIES);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002171
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002172 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2173 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002174 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
2175 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002176 return err;
2177 }
2178
2179 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2180 direction.c_str(), tm_sched_key.id, intf_id);
2181 return BCM_ERR_OK;
2182}
2183
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002184bcmos_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 -07002185 uint32_t alloc_id, ::tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
2186 ::tech_profile::SchedulingPolicy sched_policy, ::tech_profile::TrafficShapingInfo tf_sh_info,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002187 uint32_t tech_profile_id) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002188
2189 bcmos_errno err;
2190
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002191 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002192 bcmolt_tm_sched_cfg tm_sched_cfg;
2193 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002194 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 -04002195
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002196 // bcmbal_tm_sched_owner
2197 // In downstream it is sub_term scheduler
2198 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002199
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002200 /**< The output of the tm_sched object instance */
2201 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002202
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002203 // bcmbal_tm_sched_parent
2204 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2205 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
2206 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 +00002207 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002208 be achieved using the' virtual' type of attachment.
2209 tm_sched_owner.u.sub_term.intf_id = intf_id;
2210 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2211 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002212
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002213 // bcmbal_tm_sched_type
2214 // set the deafult policy to strict priority
2215 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002216
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002217 // num_priorities: Max number of strict priority scheduling elements
2218 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002219
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002220 // bcmbal_tm_shaping
2221 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2222 uint32_t cir = tf_sh_info.cir();
2223 uint32_t pir = tf_sh_info.pir();
2224 uint32_t burst = tf_sh_info.pbs();
2225 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2226 cir, pir, burst);
2227 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2228 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2229 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2230 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2231 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2232 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002233 }
2234
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002235 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002236 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002237 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002238intf_id %d, onu_id %d, uni_id %d, port_no %u, err = %s\n", tm_sched_key.id, intf_id, onu_id, uni_id, \
2239port_no, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002240 return err;
2241 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002242 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2243uni_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 -08002244
2245 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002246 bcmolt_itupon_alloc_cfg cfg;
2247 bcmolt_itupon_alloc_key key = { };
2248 key.pon_ni = intf_id;
2249 key.alloc_id = alloc_id;
2250 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
Burak Gurdag03919c72020-02-04 22:46:57 +00002251 int pir_bw = tf_sh_info.pir()*125; // conversion from kbps to bytes/sec
2252 int cir_bw = tf_sh_info.cir()*125; // conversion from kbps to bytes/sec
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002253 //offset to match bandwidth granularity
2254 int offset_pir_bw = pir_bw%bw_granularity;
2255 int offset_cir_bw = cir_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002256
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002257 pir_bw = pir_bw - offset_pir_bw;
2258 cir_bw = cir_bw - offset_cir_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002259
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002260 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002261
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002262 switch (additional_bw) {
2263 case 2: //AdditionalBW_BestEffort
2264 if (pir_bw == 0) {
2265 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2266%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002267 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002268 } else if (pir_bw < cir_bw) {
2269 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2270bandwidth (%d)\n", pir_bw, cir_bw);
2271 return BCM_ERR_PARM;
2272 } else if (pir_bw == cir_bw) {
2273 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2274bandwidth for additional bandwidth eligibility of type best_effort\n");
2275 return BCM_ERR_PARM;
2276 }
2277 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2278 break;
2279 case 1: //AdditionalBW_NA
2280 if (pir_bw == 0) {
2281 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2282%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2283 return BCM_ERR_PARM;
2284 } else if (cir_bw == 0) {
2285 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2286additional bandwidth eligibility of type Non-Assured (NA)\n");
2287 return BCM_ERR_PARM;
2288 } else if (pir_bw < cir_bw) {
2289 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2290bandwidth (%d)\n", pir_bw, cir_bw);
2291 return BCM_ERR_PARM;
2292 } else if (pir_bw == cir_bw) {
2293 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2294bandwidth for additional bandwidth eligibility of type non_assured\n");
2295 return BCM_ERR_PARM;
2296 }
2297 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2298 break;
2299 case 0: //AdditionalBW_None
2300 if (pir_bw == 0) {
2301 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
230216000 bytes/sec\n");
2303 return BCM_ERR_PARM;
2304 } else if (cir_bw == 0) {
2305 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2306for additional bandwidth eligibility of type None\n");
2307 return BCM_ERR_PARM;
2308 } else if (pir_bw > cir_bw) {
2309 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2310for additional bandwidth eligibility of type None\n");
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002311 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002312bandwidth in None eligibility\n", pir_bw);
2313 cir_bw = pir_bw;
2314 } else if (pir_bw < cir_bw) {
2315 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2316bandwidth (%d)\n", pir_bw, cir_bw);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002317 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002318bandwidth in None eligibility\n", pir_bw);
2319 cir_bw = pir_bw;
2320 }
2321 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2322 break;
2323 default:
2324 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002325 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002326 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2327 in a fine granularity. */
2328 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
2329 /* Fixed Bandwidth with no critical requirement of shaping */
2330 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, 0);
2331 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
2332 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, cir_bw);
2333 /* Maximum allocated bandwidth allowed for this alloc ID */
2334 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
2335 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002336 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002337 for skipped allocations during quiet window */
2338 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2339 /**< Allocation Profile index for CBR non-RT Bandwidth */
2340 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2341 /**< Allocation Profile index for CBR RT Bandwidth */
2342 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2343 /**< Alloc ID Weight used in case of Extended DBA mode */
2344 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2345 /**< Alloc ID Priority used in case of Extended DBA mode */
2346 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2347 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002348
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002349 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002350 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002351 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 -05002352port_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 -08002353 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002354 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002355#ifndef SCALE_AND_PERF
Girish Gowdra96461052019-11-22 20:13:59 +05302356 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
2357 if (err) {
2358 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2359port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
2360 return err;
2361 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002362#endif
Girish Gowdra96461052019-11-22 20:13:59 +05302363
2364 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
2365port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
2366
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002367 }
2368
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002369 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002370}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002371
Girish Gowdra252f4972020-09-07 21:24:01 -07002372Status CreateTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002373 uint32_t intf_id = traffic_scheds->intf_id();
2374 uint32_t onu_id = traffic_scheds->onu_id();
2375 uint32_t uni_id = traffic_scheds->uni_id();
2376 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002377 std::string direction;
2378 unsigned int alloc_id;
Girish Gowdra252f4972020-09-07 21:24:01 -07002379 ::tech_profile::SchedulerConfig sched_config;
2380 ::tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002381 uint32_t priority;
2382 uint32_t weight;
Girish Gowdra252f4972020-09-07 21:24:01 -07002383 ::tech_profile::SchedulingPolicy sched_policy;
2384 ::tech_profile::TrafficShapingInfo traffic_shaping_info;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002385 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002386 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002387
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002388 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002389 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002390
2391 direction = GetDirection(traffic_sched.direction());
2392 if (direction.compare("direction-not-supported") == 0)
2393 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2394
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002395 alloc_id = traffic_sched.alloc_id();
2396 sched_config = traffic_sched.scheduler();
2397 additional_bw = sched_config.additional_bw();
2398 priority = sched_config.priority();
2399 weight = sched_config.weight();
2400 sched_policy = sched_config.sched_policy();
2401 traffic_shaping_info = traffic_sched.traffic_shaping_info();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002402 tech_profile_id = traffic_sched.tech_profile_id();
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002403 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002404 sched_policy, traffic_shaping_info, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002405 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002406 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002407 return bcm_to_grpc_err(err, "Failed to create scheduler");
2408 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002409 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002410 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002411}
Jonathan Davis70c21812018-07-19 15:32:10 -04002412
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002413bcmos_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 -04002414
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002415 bcmos_errno err;
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302416 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302417 bcmolt_status los_status;
Girish Gowdra96461052019-11-22 20:13:59 +05302418 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002419
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002420 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002421 bcmolt_itupon_alloc_cfg cfg;
2422 bcmolt_itupon_alloc_key key = { };
2423 key.pon_ni = intf_id;
2424 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302425 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002426
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002427 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002428 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2429 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002430 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2431 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002432 return err;
2433 }
Girish Gowdra96461052019-11-22 20:13:59 +05302434
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302435 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302436 if (err == BCM_ERR_OK) {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302437 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_OFF) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002438#ifndef SCALE_AND_PERF
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302439 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 +05302440 intf_id);
2441 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2442 if (err) {
2443 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2444 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
2445 return err;
2446 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002447#endif
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302448 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302449 else if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_ON) {
2450 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is enabled but LoS status is ON, not waiting for alloc cfg clear response\n",
2451 intf_id);
2452 }
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302453 else if (state == BCMOLT_INTERFACE_STATE_INACTIVE) {
2454 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is disabled, not waiting for alloc cfg clear response\n",
2455 intf_id);
2456 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302457 } else {
2458 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 +05302459 intf_id, bcmos_strerror(err));
Girish Gowdra96461052019-11-22 20:13:59 +05302460 return err;
2461 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002462 } else if (direction == downstream) {
2463 bcmolt_tm_sched_cfg cfg;
2464 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002465
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002466 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2467 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302468 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002469 } else {
2470 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2471 return BCM_ERR_OK;
2472 }
Girish Gowdra96461052019-11-22 20:13:59 +05302473
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002474 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2475 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2476 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002477 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002478intf_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 +00002479 return err;
2480 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002481 }
2482
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002483 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d, tech_profile_id %d\n",
2484 direction.c_str(), sched_id, intf_id, onu_id, tech_profile_id);
2485 free_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002486 return BCM_ERR_OK;
2487}
2488
Girish Gowdra252f4972020-09-07 21:24:01 -07002489Status RemoveTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002490 uint32_t intf_id = traffic_scheds->intf_id();
2491 uint32_t onu_id = traffic_scheds->onu_id();
2492 uint32_t uni_id = traffic_scheds->uni_id();
2493 std::string direction;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002494 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002495 bcmos_errno err;
2496
2497 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002498 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002499
2500 direction = GetDirection(traffic_sched.direction());
2501 if (direction.compare("direction-not-supported") == 0)
2502 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2503
2504 int alloc_id = traffic_sched.alloc_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002505 int tech_profile_id = traffic_sched.tech_profile_id();
2506 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002507 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002508 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002509 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2510 }
2511 }
2512 return Status::OK;
2513}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002514
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002515bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2516 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002517 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002518 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2519 bcmolt_tm_qmp_key tm_qmp_key;
2520 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002521
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002522 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2523 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002524 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed tm queue mapping profile count is 16.\n");
2525 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002526 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002527
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002528 tm_qmp_key.id = tm_qmp_id;
2529 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2530 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2531 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002532
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002533 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2534 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2535 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002536 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2537 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002538
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002539 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002540 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002541 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2542 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002543 return err;
2544 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002545
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002546 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2547 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002548 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002549}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002550
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002551bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2552 bcmos_errno err;
2553 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2554 bcmolt_tm_qmp_key tm_qmp_key;
2555 tm_qmp_key.id = tm_qmp_id;
2556
2557 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2558 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2559 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002560 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2561 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002562 return err;
2563 }
2564
2565 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2566 tm_qmp_key.id);
2567 return BCM_ERR_OK;
2568}
2569
2570bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2571 bcmos_errno err;
2572
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002573 /* Create default queues on the given PON/NNI scheduler */
2574 for (int queue_id = 0; queue_id < NUMBER_OF_DEFAULT_INTERFACE_QUEUES; queue_id++) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002575 bcmolt_tm_queue_cfg tm_queue_cfg;
2576 bcmolt_tm_queue_key tm_queue_key = {};
2577 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2578 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002579 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2580 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2581 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002582
2583 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2584 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2585 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2586
2587 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2588 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002589 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", \
2590 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 +00002591 return err;
2592 }
2593
2594 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2595 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2596 }
2597 return BCM_ERR_OK;
2598}
2599
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002600bcmos_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 +00002601 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 +00002602 bcmos_errno err;
2603 bcmolt_tm_queue_cfg cfg;
2604 bcmolt_tm_queue_key key = { };
2605 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 +00002606gemport_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 +00002607
2608 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002609 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002610
2611 if (priority > 7) {
2612 return BCM_ERR_RANGE;
2613 }
2614
2615 /* FIXME: The upstream queues have to be created once only.
2616 The upstream queues on the NNI scheduler are shared by all subscribers.
2617 When the first scheduler comes in, the queues get created, and are re-used by all others.
2618 Also, these queues should be present until the last subscriber exits the system.
2619 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2620
2621 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2622 for each GEM in TECH PROFILE */
2623 key.id = queue_id_list[priority];
2624
2625 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2626 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2627 key.id = 0;
2628 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2629 }
2630 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2631 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2632 }
2633 else {
2634 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2635 }
2636
2637 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2638
2639 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2640 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
2641
2642 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2643 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002644 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002645sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, tech_profile_id %d, err = %s\n", \
2646 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 +00002647 return err;
2648 }
2649
Girish Gowdra252f4972020-09-07 21:24:01 -07002650 if (direction.compare(upstream) == 0) {
2651 Status st = install_gem_port(access_intf_id, onu_id, gemport_id);
2652 if (st.error_code() != grpc::StatusCode::ALREADY_EXISTS && st.error_code() != grpc::StatusCode::OK) {
2653 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);
2654 return BCM_ERR_INTERNAL;
2655 }
2656 }
2657
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002658 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 +00002659intf_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 +00002660 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002661}
2662
Girish Gowdra252f4972020-09-07 21:24:01 -07002663Status CreateTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002664 uint32_t intf_id = traffic_queues->intf_id();
2665 uint32_t onu_id = traffic_queues->onu_id();
2666 uint32_t uni_id = traffic_queues->uni_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002667 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002668 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002669 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002670 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002671 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 +00002672
2673 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2674 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2675 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2676 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002677 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002678
2679 direction = GetDirection(traffic_queue.direction());
2680 if (direction.compare("direction-not-supported") == 0)
2681 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2682
2683 queues_priority_q[i] = traffic_queue.priority();
2684 queues_pbit_map[i] = traffic_queue.pbit_map();
2685 }
2686
2687 std::vector<uint32_t> tmq_map_profile(8, 0);
2688 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2689 queues_priority_q, COUNT_OF(queues_priority_q));
2690 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002691 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002692
2693 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2694 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002695 err = CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2696 if (err != BCM_ERR_OK) {
2697 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2698 return bcm_to_grpc_err(err, "Failed to create tm queue mapping profile");
2699 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002700 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2701 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2702 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2703 }
2704 }
2705
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002706 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002707 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002708
2709 direction = GetDirection(traffic_queue.direction());
2710 if (direction.compare("direction-not-supported") == 0)
2711 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2712
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002713 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 +00002714
Girish Gowdruf26cf882019-05-01 23:47:58 -07002715 // If the queue exists already, lets not return failure and break the loop.
2716 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002717 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002718 return bcm_to_grpc_err(err, "Failed to create queue");
2719 }
2720 }
2721 return Status::OK;
2722}
2723
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002724bcmos_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 +00002725 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 +00002726 bcmolt_tm_queue_cfg cfg;
2727 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002728 bcmos_errno err;
2729
2730 if (direction == downstream) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002731 // Gem ports are HSI/VoIP/VoD traffic is bidirectional. Multicast gem-port are downstream only. Since the common direction between
2732 // bidirectional traffic and multicast gem-port is "downstream" direction and we need to remove the gemport for a given gemport id only once,
2733 // we remove the gem port when downstream direction queue is getting removed.
2734 remove_gem_port(access_intf_id, gemport_id);
2735
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002736 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2737 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 +00002738 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002739 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002740 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 -08002741 return BCM_ERR_OK;
2742 }
2743 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002744 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2745 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002746 return BCM_ERR_OK;
2747 }
2748
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002749 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2750 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2751 // Reset the queue id to 0 when using fixed queue.
2752 key.id = 0;
2753 }
2754 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2755 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2756 }
2757 else {
2758 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2759 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002760
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002761 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2762 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002763 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002764 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, queue_id %d, sched_id %d, \
2765tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n",
2766 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 -08002767 return err;
2768 }
2769
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002770 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2771intf_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 -08002772
2773 return BCM_ERR_OK;
2774}
2775
Girish Gowdra252f4972020-09-07 21:24:01 -07002776Status RemoveTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002777 uint32_t intf_id = traffic_queues->intf_id();
2778 uint32_t onu_id = traffic_queues->onu_id();
2779 uint32_t uni_id = traffic_queues->uni_id();
2780 uint32_t port_no = traffic_queues->port_no();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002781 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002782 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002783 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002784 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002785 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 +00002786
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002787 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002788 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002789
2790 direction = GetDirection(traffic_queue.direction());
2791 if (direction.compare("direction-not-supported") == 0)
2792 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2793
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002794 err = 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 -08002795 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002796 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002797 return bcm_to_grpc_err(err, "Failed to remove queue");
2798 }
Jonathan Davis70c21812018-07-19 15:32:10 -04002799 }
2800
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002801 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 +00002802 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002803 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002804
2805 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
2806 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002807 err = RemoveTrafficQueueMappingProfile(tm_qmp_id);
2808 if (err != BCM_ERR_OK) {
2809 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2810 return bcm_to_grpc_err(err, "Failed to remove tm queue mapping profile");
2811 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002812 }
2813 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002814 clear_qos_type(intf_id, onu_id, uni_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04002815 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04002816}
Jason Huangbf45ffb2019-10-30 17:29:02 +08002817
Girish Gowdra252f4972020-09-07 21:24:01 -07002818Status PerformGroupOperation_(const ::openolt::Group *group_cfg) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002819
2820 bcmos_errno err;
2821 bcmolt_group_key key = {};
2822 bcmolt_group_cfg grp_cfg_obj;
2823 bcmolt_group_members_update grp_mem_upd;
2824 bcmolt_members_update_command grp_mem_upd_cmd;
2825 bcmolt_group_member_info member_info = {};
2826 bcmolt_group_member_info_list_u8 members = {};
2827 bcmolt_intf_ref interface_ref = {};
2828 bcmolt_egress_qos egress_qos = {};
2829 bcmolt_tm_sched_ref tm_sched_ref = {};
2830 bcmolt_action a_val = {};
2831
2832 uint32_t group_id = group_cfg->group_id();
2833
2834 OPENOLT_LOG(INFO, openolt_log_id, "PerformGroupOperation request received for Group %d\n", group_id);
2835
2836 if (group_id >= 0) {
2837 key.id = group_id;
2838 }
2839 else {
2840 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
2841 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
2842 }
2843
2844 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2845 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
2846
2847 OPENOLT_LOG(INFO, openolt_log_id, "Checking if Group %d exists...\n",group_id);
2848
2849 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
2850 if (err != BCM_ERR_OK) {
2851 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
2852 return bcm_to_grpc_err(err, "Error in querying group");
2853 }
2854
2855 members.len = group_cfg->members_size();
2856
2857 // IMPORTANT: A member cannot be added to a group if the group type is not determined.
2858 // Group type is determined after a flow is assigned to it.
2859 // Therefore, a group must be created first, then a flow (with multicast type) must be assigned to it.
2860 // Only then we can add members to the group.
2861
2862 // if group does not exist, create it and return.
2863 if (grp_cfg_obj.data.state == BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
2864
2865 if (members.len != 0) {
2866 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);
2867 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Non-empty member list given for non-existent group");
2868 } else {
2869
2870 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2871 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, cookie, key.id);
2872
2873 /* Setting group actions and action parameters, if any.
2874 Only remove_outer_tag and translate_inner_tag actions and i_vid action parameter
2875 are supported for multicast groups in BAL 3.1.
2876 */
2877 const ::openolt::Action& action = group_cfg->action();
2878 const ::openolt::ActionCmd &cmd = action.cmd();
2879
2880 bcmolt_action_cmd_id cmd_bmask = BCMOLT_ACTION_CMD_ID_NONE;
2881 if (cmd.remove_outer_tag()) {
2882 OPENOLT_LOG(INFO, openolt_log_id, "Action remove_outer_tag applied to Group %d.\n", group_id);
2883 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
2884 }
2885
2886 if (cmd.translate_inner_tag()) {
2887 OPENOLT_LOG(INFO, openolt_log_id, "Action translate_inner_tag applied to Group %d.\n", group_id);
2888 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG);
2889 }
2890
2891 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, cmd_bmask);
2892
2893 if (action.i_vid()) {
2894 OPENOLT_LOG(INFO, openolt_log_id, "Setting action parameter i_vid=%d for Group %d.\n", action.i_vid(), group_id);
2895 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
2896 }
2897
2898 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, action, a_val);
2899
2900 // Create group
2901 err = bcmolt_cfg_set(dev_id, &(grp_cfg_obj.hdr));
2902
2903 if (BCM_ERR_OK != err) {
2904 BCM_LOG(ERROR, openolt_log_id, "Failed to create Group %d, err = %s (%d)\n", key.id, bcmos_strerror(err), err);
2905 return bcm_to_grpc_err(err, "Error in creating group");
2906 }
2907
2908 BCM_LOG(INFO, openolt_log_id, "Group %d has been created and configured with empty member list.\n", key.id);
2909 return Status::OK;
2910 }
2911 }
2912
2913 // The group already exists. Continue configuring it according to the update member command.
2914
2915 OPENOLT_LOG(INFO, openolt_log_id, "Configuring existing Group %d.\n",group_id);
2916
2917 // MEMBER LIST CONSTRUCTION
2918 // Note that members.len can be 0 here. if the group already exists and the command is SET then sending
2919 // empty list to the group is a legit operation and this actually empties the member list.
2920 members.arr = (bcmolt_group_member_info*)bcmos_calloc((members.len)*sizeof(bcmolt_group_member_info));
2921
2922 if (!members.arr) {
2923 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to allocate memory for group member list.\n");
2924 return grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "Memory exhausted during member list creation");
2925 }
2926
2927 /* SET GROUP MEMBERS UPDATE COMMAND */
Girish Gowdra252f4972020-09-07 21:24:01 -07002928 ::openolt::Group::GroupMembersCommand command = group_cfg->command();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002929 switch(command) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002930 case ::openolt::Group::SET_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002931 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_SET;
2932 OPENOLT_LOG(INFO, openolt_log_id, "Setting %d members for Group %d.\n", members.len, group_id);
2933 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07002934 case ::openolt::Group::ADD_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002935 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_ADD;
2936 OPENOLT_LOG(INFO, openolt_log_id, "Adding %d members to Group %d.\n", members.len, group_id);
2937 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07002938 case ::openolt::Group::REMOVE_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002939 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_REMOVE;
2940 OPENOLT_LOG(INFO, openolt_log_id, "Removing %d members from Group %d.\n", members.len, group_id);
2941 break;
2942 default :
2943 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid value %d for group member command.\n", command);
2944 bcmos_free(members.arr);
2945 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group member command");
2946 }
2947
2948 // SET MEMBERS LIST
2949 for (int i = 0; i < members.len; i++) {
2950
Girish Gowdra252f4972020-09-07 21:24:01 -07002951 if (command == ::openolt::Group::REMOVE_MEMBERS) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002952 OPENOLT_LOG(INFO, openolt_log_id, "Removing group member %d from group %d\n",i,key.id);
2953 } else {
2954 OPENOLT_LOG(INFO, openolt_log_id, "Adding group member %d to group %d\n",i,key.id);
2955 }
2956
Girish Gowdra252f4972020-09-07 21:24:01 -07002957 ::openolt::GroupMember *member = (::openolt::GroupMember *) &group_cfg->members()[i];
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002958
2959 // Set member interface type
Girish Gowdra252f4972020-09-07 21:24:01 -07002960 ::openolt::GroupMember::InterfaceType if_type = member->interface_type();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002961 switch(if_type){
Girish Gowdra252f4972020-09-07 21:24:01 -07002962 case ::openolt::GroupMember::PON :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002963 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_PON);
2964 OPENOLT_LOG(INFO, openolt_log_id, "Interface type PON is assigned to GroupMember %d\n",i);
2965 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07002966 case ::openolt::GroupMember::EPON_1G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002967 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_1_G);
2968 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_1G is assigned to GroupMember %d\n",i);
2969 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07002970 case ::openolt::GroupMember::EPON_10G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002971 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_10_G);
2972 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_10G is assigned to GroupMember %d\n",i);
2973 break;
2974 default :
2975 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid interface type value %d for GroupMember %d.\n",if_type,i);
2976 bcmos_free(members.arr);
2977 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface type for a group member");
2978 }
2979
2980 // Set member interface id
2981 if (member->interface_id() >= 0) {
2982 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_id, member->interface_id());
2983 OPENOLT_LOG(INFO, openolt_log_id, "Interface %d is assigned to GroupMember %d\n", member->interface_id(), i);
2984 } else {
2985 bcmos_free(members.arr);
2986 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface id for a group member");
2987 }
2988
2989 // Set member interface_ref
2990 BCMOLT_FIELD_SET(&member_info, group_member_info, intf, interface_ref);
2991
2992 // Set member gem_port_id. This must be a multicast gemport.
2993 if (member->gem_port_id() >= 0) {
2994 BCMOLT_FIELD_SET(&member_info, group_member_info, svc_port_id, member->gem_port_id());
2995 OPENOLT_LOG(INFO, openolt_log_id, "GEM Port %d is assigned to GroupMember %d\n", member->gem_port_id(), i);
2996 } else {
2997 bcmos_free(members.arr);
2998 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid gem port id for a group member");
2999 }
3000
3001 // Set member scheduler id and queue_id
3002 uint32_t tm_sched_id = get_default_tm_sched_id(member->interface_id(), downstream);
3003 OPENOLT_LOG(INFO, openolt_log_id, "Scheduler %d is assigned to GroupMember %d\n", tm_sched_id, i);
3004 BCMOLT_FIELD_SET(&tm_sched_ref, tm_sched_ref, id, tm_sched_id);
3005 BCMOLT_FIELD_SET(&egress_qos, egress_qos, tm_sched, tm_sched_ref);
3006
3007 // We assume that all multicast traffic destined to a PON port is using the same fixed queue.
3008 uint32_t tm_queue_id;
3009 if (member->priority() >= 0 && member->priority() < NUMBER_OF_DEFAULT_INTERFACE_QUEUES) {
3010 tm_queue_id = queue_id_list[member->priority()];
3011 OPENOLT_LOG(INFO, openolt_log_id, "Queue %d is assigned to GroupMember %d\n", tm_queue_id, i);
3012 BCMOLT_FIELD_SET(&egress_qos, egress_qos, type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
3013 BCMOLT_FIELD_SET(&egress_qos.u.fixed_queue, egress_qos_fixed_queue, queue_id, tm_queue_id);
3014 } else {
3015 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid fixed queue priority/ID %d for GroupMember %d\n", member->priority(), i);
3016 bcmos_free(members.arr);
3017 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid queue priority for a group member");
3018 }
3019
3020 BCMOLT_FIELD_SET(&member_info, group_member_info, egress_qos, egress_qos);
3021 BCMOLT_ARRAY_ELEM_SET(&(members), i, member_info);
3022 }
3023
3024 BCMOLT_OPER_INIT(&grp_mem_upd, group, members_update, key);
3025 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.members, members);
3026 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.command, grp_mem_upd_cmd);
3027
3028 err = bcmolt_oper_submit(dev_id, &(grp_mem_upd.hdr));
3029 bcmos_free(members.arr);
3030
3031 if (BCM_ERR_OK != err) {
3032 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);
3033 return bcm_to_grpc_err(err, "Failed to submit members update operation for the group");
3034 }
3035
3036 OPENOLT_LOG(INFO, openolt_log_id, "Successfully submitted members update operation for Group %d\n", key.id);
3037
3038 return Status::OK;
3039}
Burak Gurdageb4ca2e2020-06-15 07:48:26 +00003040
3041Status DeleteGroup_(uint32_t group_id) {
3042
3043 bcmos_errno err = BCM_ERR_OK;
3044 bcmolt_group_cfg grp_cfg_obj;
3045 bcmolt_group_key key = {};
3046
3047
3048 OPENOLT_LOG(INFO, openolt_log_id, "Delete request received for group %d\n", group_id);
3049
3050 if (group_id >= 0) {
3051 key.id = group_id;
3052 } else {
3053 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
3054 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
3055 }
3056
3057 /* init the BAL INIT API */
3058 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3059
3060 OPENOLT_LOG(DEBUG, openolt_log_id, "Checking if group %d exists...\n",group_id);
3061
3062 // CONFIGURE GROUP MEMBERS
3063 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
3064 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
3065
3066 if (err != BCM_ERR_OK) {
3067 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
3068 return bcm_to_grpc_err(err, "Error in querying group");
3069 }
3070
3071 if (grp_cfg_obj.data.state != BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
3072 OPENOLT_LOG(DEBUG, openolt_log_id, "Group %d exists. Will be deleted.\n",group_id);
3073 err = bcmolt_cfg_clear(dev_id, &(grp_cfg_obj.hdr));
3074 if (err != BCM_ERR_OK) {
3075 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d cannot be deleted err = %s (%d).\n", group_id, bcmos_strerror(err), err);
3076 return bcm_to_grpc_err(err, "Failed to delete group");;
3077 }
3078 } else {
3079 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d does not exist.\n", group_id);
3080 return Status(grpc::StatusCode::NOT_FOUND, "Group not found");
3081 }
3082
3083 OPENOLT_LOG(INFO, openolt_log_id, "Group %d has been deleted successfully.\n", group_id);
3084 return Status::OK;
Jason Huang1d9cfce2020-05-20 22:58:47 +08003085}
3086
Girish Gowdra252f4972020-09-07 21:24:01 -07003087Status GetLogicalOnuDistanceZero_(uint32_t intf_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003088 bcmos_errno err = BCM_ERR_OK;
3089 uint32_t mld = 0;
3090 double LD0;
3091
3092 err = getOnuMaxLogicalDistance(intf_id, &mld);
3093 if (err != BCM_ERR_OK) {
3094 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3095 }
3096
3097 LD0 = LOGICAL_DISTANCE(mld*1000, MINIMUM_ONU_RESPONSE_RANGING_TIME, ONU_BIT_TRANSMISSION_DELAY);
3098 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance zero is %f, (PON %d)\n", LD0, intf_id);
3099 response->set_intf_id(intf_id);
3100 response->set_logical_onu_distance_zero(LD0);
3101
3102 return Status::OK;
3103}
3104
Girish Gowdra252f4972020-09-07 21:24:01 -07003105Status GetLogicalOnuDistance_(uint32_t intf_id, uint32_t onu_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003106 bcmos_errno err = BCM_ERR_OK;
3107 bcmolt_itu_onu_params itu = {};
3108 bcmolt_onu_cfg onu_cfg;
3109 bcmolt_onu_key onu_key = {};
3110 uint32_t mld = 0;
3111 double LDi;
3112
3113 onu_key.pon_ni = intf_id;
3114 onu_key.onu_id = onu_id;
3115
3116 err = getOnuMaxLogicalDistance(intf_id, &mld);
3117 if (err != BCM_ERR_OK) {
3118 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3119 }
3120
3121 /* Initialize the API struct. */
3122 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
3123 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
3124 BCMOLT_FIELD_SET_PRESENT(&itu, itu_onu_params, ranging_time);
3125 BCMOLT_FIELD_SET(&onu_cfg.data, onu_cfg_data, itu, itu);
3126 #ifdef TEST_MODE
3127 // It is impossible to mock the setting of onu_cfg.data.onu_state because
3128 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
3129 // set the onu_cfg.data.onu_state. So a new stub function is created and address
3130 // of onu_cfg is passed. This is one-of case where we need to add test specific
3131 // code in production code.
3132 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
3133 #else
3134 /* Call API function. */
3135 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
3136 #endif
3137 if (err != BCM_ERR_OK) {
3138 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);
3139 return bcm_to_grpc_err(err, "Failed to retrieve ONU ranging time");
3140 }
3141
3142 if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_ACTIVE) {
3143 OPENOLT_LOG(ERROR, openolt_log_id, "ONU is not yet activated (PON %d, ONU id %d)\n", intf_id, onu_id);
3144 return bcm_to_grpc_err(BCM_ERR_PARM, "ONU is not yet activated\n");
3145 }
3146
3147 LDi = LOGICAL_DISTANCE(mld*1000, onu_cfg.data.itu.ranging_time, ONU_BIT_TRANSMISSION_DELAY);
3148 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance is %f, (PON %d, ONU id %d)\n", LDi, intf_id, onu_id);
3149 response->set_intf_id(intf_id);
3150 response->set_onu_id(onu_id);
3151 response->set_logical_onu_distance(LDi);
3152
3153 return Status::OK;
3154}