blob: 1579a4f1831572523ee2930771df3481abde70c4 [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);
Orhan Kupusogluec57af02021-05-12 12:38:17 +000078static const std::chrono::milliseconds ONU_RSSI_COMPLETE_WAIT_TIMEOUT = std::chrono::seconds(10);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000079
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000080inline const char *get_flow_acton_command(uint32_t command) {
81 char actions[200] = { };
82 char *s_actions_ptr = actions;
83 if (command & BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG) strcat(s_actions_ptr, "ADD_OUTER_TAG|");
84 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG) strcat(s_actions_ptr, "REMOVE_OUTER_TAG|");
85 if (command & BCMOLT_ACTION_CMD_ID_XLATE_OUTER_TAG) strcat(s_actions_ptr, "TRANSLATE_OUTER_TAG|");
86 if (command & BCMOLT_ACTION_CMD_ID_ADD_INNER_TAG) strcat(s_actions_ptr, "ADD_INNTER_TAG|");
87 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_INNER_TAG) strcat(s_actions_ptr, "REMOVE_INNER_TAG|");
88 if (command & BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG) strcat(s_actions_ptr, "TRANSLATE_INNER_TAG|");
89 if (command & BCMOLT_ACTION_CMD_ID_REMARK_OUTER_PBITS) strcat(s_actions_ptr, "REMOVE_OUTER_PBITS|");
90 if (command & BCMOLT_ACTION_CMD_ID_REMARK_INNER_PBITS) strcat(s_actions_ptr, "REMAKE_INNER_PBITS|");
91 return s_actions_ptr;
92}
93
kesavandc1f2db92020-08-31 15:32:06 +053094bcmolt_stat_alarm_config set_stat_alarm_config(const config::OnuItuPonAlarm* request) {
Jason Huang5d9ab1a2020-04-15 16:53:49 +080095 bcmolt_stat_alarm_config alarm_cfg = {};
96 bcmolt_stat_alarm_trigger_config trigger_obj = {};
97 bcmolt_stat_alarm_soak_config soak_obj = {};
98
99 switch (request->alarm_reporting_condition()) {
kesavandc1f2db92020-08-31 15:32:06 +0530100 case config::OnuItuPonAlarm::RATE_THRESHOLD:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800101 trigger_obj.type = BCMOLT_STAT_CONDITION_TYPE_RATE_THRESHOLD;
102 BCMOLT_FIELD_SET(&trigger_obj.u.rate_threshold, stat_alarm_trigger_config_rate_threshold,
103 rising, request->rate_threshold_config().rate_threshold_rising());
104 BCMOLT_FIELD_SET(&trigger_obj.u.rate_threshold, stat_alarm_trigger_config_rate_threshold,
105 falling, request->rate_threshold_config().rate_threshold_falling());
106 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, active_soak_time,
107 request->rate_threshold_config().soak_time().active_soak_time());
108 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, clear_soak_time,
109 request->rate_threshold_config().soak_time().clear_soak_time());
110 break;
kesavandc1f2db92020-08-31 15:32:06 +0530111 case config::OnuItuPonAlarm::RATE_RANGE:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800112 trigger_obj.type = BCMOLT_STAT_CONDITION_TYPE_RATE_RANGE;
113 BCMOLT_FIELD_SET(&trigger_obj.u.rate_range, stat_alarm_trigger_config_rate_range, upper,
114 request->rate_range_config().rate_range_upper());
115 BCMOLT_FIELD_SET(&trigger_obj.u.rate_range, stat_alarm_trigger_config_rate_range, lower,
116 request->rate_range_config().rate_range_lower());
117 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, active_soak_time,
118 request->rate_range_config().soak_time().active_soak_time());
119 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, clear_soak_time,
120 request->rate_range_config().soak_time().clear_soak_time());
121 break;
kesavandc1f2db92020-08-31 15:32:06 +0530122 case config::OnuItuPonAlarm::VALUE_THRESHOLD:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800123 trigger_obj.type = BCMOLT_STAT_CONDITION_TYPE_VALUE_THRESHOLD;
124 BCMOLT_FIELD_SET(&trigger_obj.u.value_threshold, stat_alarm_trigger_config_value_threshold,
125 limit, request->value_threshold_config().threshold_limit());
126 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, active_soak_time,
127 request->value_threshold_config().soak_time().active_soak_time());
128 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, clear_soak_time,
129 request->value_threshold_config().soak_time().clear_soak_time());
130 break;
131 default:
132 OPENOLT_LOG(ERROR, openolt_log_id, "unsupported alarm reporting condition = %u\n", request->alarm_reporting_condition());
133 // For now just log the error and not return error. We can handle this scenario in the future.
134 break;
135 }
136
137 BCMOLT_FIELD_SET(&alarm_cfg, stat_alarm_config, trigger, trigger_obj);
138 BCMOLT_FIELD_SET(&alarm_cfg, stat_alarm_config, soak, soak_obj);
139
140 return alarm_cfg;
141}
142
kesavandc1f2db92020-08-31 15:32:06 +0530143Status OnuItuPonAlarmSet_(const config::OnuItuPonAlarm* request) {
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800144 bcmos_errno err;
145 bcmolt_onu_itu_pon_stats_cfg stat_cfg; /* declare main API struct */
146 bcmolt_onu_key key = {}; /* declare key */
147 bcmolt_stat_alarm_config errors_cfg = {};
148
149 key.pon_ni = request->pon_ni();
150 key.onu_id = request->onu_id();
151
152 /* Initialize the API struct. */
153 BCMOLT_STAT_CFG_INIT(&stat_cfg, onu, itu_pon_stats, key);
154
155 /*
156 1. BCMOLT_STAT_CONDITION_TYPE_NONE = 0, The alarm is disabled.
157 2. BCMOLT_STAT_CONDITION_TYPE_RATE_THRESHOLD = 1, The alarm is triggered if the stats delta value between samples
158 crosses the configured threshold boundary.
159 rising: The alarm is raised if the stats delta value per second becomes greater than this threshold level.
160 falling: The alarm is cleared if the stats delta value per second becomes less than this threshold level.
161 3. BCMOLT_STAT_CONDITION_TYPE_RATE_RANGE = 2, The alarm is triggered if the stats delta value between samples
162 deviates from the configured range.
163 upper: The alarm is raised if the stats delta value per second becomes greater than this upper level.
164 lower: The alarm is raised if the stats delta value per second becomes less than this lower level.
165 4. BCMOLT_STAT_CONDITION_TYPE_VALUE_THRESHOLD = 3, The alarm is raised if the stats sample value becomes greater
166 than this level. The alarm is cleared when the host read the stats.
167 limit: The alarm is raised if the stats sample value becomes greater than this level.
168 The alarm is cleared when the host clears the stats.
169
170 active_soak_time: If the alarm condition is raised and stays in the raised state for at least this amount
171 of time (unit=seconds), the alarm indication is sent to the host.
172 The OLT delays the alarm indication no less than this delay period.
173 It can be delayed more than this period because of the statistics sampling interval.
174 clear_soak_time: After the alarm is raised, if it is cleared and stays in the cleared state for at least
175 this amount of time (unit=seconds), the alarm indication is sent to the host.
176 The OLT delays the alarm indication no less than this delay period. It can be delayed more
177 than this period because of the statistics sampling interval.
178 */
179
180 errors_cfg = set_stat_alarm_config(request);
181
182 switch (request->alarm_id()) {
kesavandc1f2db92020-08-31 15:32:06 +0530183 case config::OnuItuPonAlarm_AlarmID::OnuItuPonAlarm_AlarmID_RDI_ERRORS:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800184 //set the rdi_errors alarm
185 BCMOLT_FIELD_SET(&stat_cfg.data, onu_itu_pon_stats_cfg_data, rdi_errors, errors_cfg);
186 break;
187 default:
188 OPENOLT_LOG(ERROR, openolt_log_id, "could not find the alarm id %d\n", request->alarm_id());
189 return bcm_to_grpc_err(BCM_ERR_PARM, "the alarm id is wrong");
190 }
191
192 err = bcmolt_stat_cfg_set(dev_id, &stat_cfg.hdr);
193 if (err != BCM_ERR_OK) {
194 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",
195 request->alarm_id(), key.pon_ni, key.onu_id, bcmos_strerror(err));
196 return bcm_to_grpc_err(err, "set Onu ITU PON stats alarm faild");
197 } else {
198 OPENOLT_LOG(INFO, openolt_log_id, "set onu itu pon stats alarm %d successfully, pon_ni %d, onu_id %d\n",
199 request->alarm_id(), key.pon_ni, key.onu_id);
200 }
201
202 return Status::OK;
203}
204
Girish Gowdra252f4972020-09-07 21:24:01 -0700205Status GetDeviceInfo_(::openolt::DeviceInfo* device_info) {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500206 device_info->set_vendor(VENDOR_ID);
207 device_info->set_model(MODEL_ID);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400208 device_info->set_hardware_version("");
209 device_info->set_firmware_version(firmware_version);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500210 device_info->set_technology(board_technology);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500211 device_info->set_pon_ports(num_of_pon_ports);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500212
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800213 char serial_number[OPENOLT_FIELD_LEN];
214 memset(serial_number, '\0', OPENOLT_FIELD_LEN);
215 openolt_read_sysinfo("Serial Number", serial_number);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000216 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device serial number %s\n", serial_number);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800217 device_info->set_device_serial_number(serial_number);
Burak Gurdag30db4822021-03-10 21:30:01 +0000218 device_info->set_previously_connected(state.previously_connected());
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800219
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700220 char device_id[OPENOLT_FIELD_LEN];
221 memset(device_id, '\0', OPENOLT_FIELD_LEN);
Humera Kouser6143c9e2020-06-17 22:37:31 +0530222
223 if (grpc_server_interface_name != NULL) {
224 if (get_intf_mac(grpc_server_interface_name, device_id, sizeof(device_id)) != NULL)
225 {
226 OPENOLT_LOG(INFO, openolt_log_id, "Fetched mac address %s of an interface %s\n", device_id, grpc_server_interface_name);
227 }
228 else
229 {
230 OPENOLT_LOG(ERROR, openolt_log_id, "Mac address of an interface %s is NULL\n", grpc_server_interface_name);
231 }
232 }
233 else
234 {
235 openolt_read_sysinfo("MAC", device_id);
236 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device mac address %s\n", device_id);
237 }
238
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700239 device_info->set_device_id(device_id);
240
Craig Lutgenb2601f02018-10-23 13:04:31 -0500241 // Legacy, device-wide ranges. To be deprecated when adapter
242 // is upgraded to support per-interface ranges
Girish Gowdra252f4972020-09-07 21:24:01 -0700243 device_info->set_onu_id_start(ONU_ID_START);
244 device_info->set_onu_id_end(ONU_ID_END);
245 device_info->set_alloc_id_start(ALLOC_ID_START);
246 device_info->set_alloc_id_end(ALLOC_ID_END);
247 device_info->set_gemport_id_start(GEM_PORT_ID_START);
248 device_info->set_gemport_id_end(GEM_PORT_ID_END);
249 device_info->set_flow_id_start(FLOW_ID_START);
250 device_info->set_flow_id_end(FLOW_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500251
Girish Gowdra252f4972020-09-07 21:24:01 -0700252 std::map<std::string, ::openolt::DeviceInfo::DeviceResourceRanges*> ranges;
Craig Lutgenb2601f02018-10-23 13:04:31 -0500253 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
254 std::string intf_technology = intf_technologies[intf_id];
Girish Gowdra252f4972020-09-07 21:24:01 -0700255 ::openolt::DeviceInfo::DeviceResourceRanges *range = ranges[intf_technology];
Craig Lutgenb2601f02018-10-23 13:04:31 -0500256 if(range == nullptr) {
257 range = device_info->add_ranges();
258 ranges[intf_technology] = range;
259 range->set_technology(intf_technology);
260
Girish Gowdra252f4972020-09-07 21:24:01 -0700261 ::openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
Craig Lutgenb2601f02018-10-23 13:04:31 -0500262
Girish Gowdra252f4972020-09-07 21:24:01 -0700263 pool = range->add_pools();
264 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
265 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
266 pool->set_start(ONU_ID_START);
267 pool->set_end(ONU_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500268
Girish Gowdra252f4972020-09-07 21:24:01 -0700269 pool = range->add_pools();
270 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
271 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
272 pool->set_start(ALLOC_ID_START);
Girish Gowdraeec0fc92021-05-12 15:37:55 -0700273 pool->set_end(ALLOC_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500274
Girish Gowdra252f4972020-09-07 21:24:01 -0700275 pool = range->add_pools();
276 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
277 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
278 pool->set_start(GEM_PORT_ID_START);
279 pool->set_end(GEM_PORT_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500280
Girish Gowdra252f4972020-09-07 21:24:01 -0700281 pool = range->add_pools();
282 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
283 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
284 pool->set_start(FLOW_ID_START);
285 pool->set_end(FLOW_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500286 }
287
288 range->add_intf_ids(intf_id);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500289 }
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400290
291 // FIXME: Once dependency problem is fixed
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500292 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400293 // device_info->set_onu_id_end(XGPON_NUM_OF_ONUS - 1);
294 // device_info->set_alloc_id_start(1024);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500295 // device_info->set_alloc_id_end(XGPON_NUM_OF_ALLOC_IDS * num_of_pon_ports ? - 1);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400296 // device_info->set_gemport_id_start(XGPON_MIN_BASE_SERVICE_PORT_ID);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500297 // device_info->set_gemport_id_end(XGPON_NUM_OF_GEM_PORT_IDS_PER_PON * num_of_pon_ports ? - 1);
298 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400299
300 return Status::OK;
301}
302
Thiyagarajan Subramani3e8bfd92021-04-26 15:07:14 +0530303void reset_pon_device(bcmolt_odid dev)
304{
305 bcmos_errno err;
306 bcmolt_device_reset oper;
307 bcmolt_device_key key = {.device_id = dev};
308
309 OPENOLT_LOG(INFO, openolt_log_id, "Reset PON device: %d\n", dev);
310
311 BCMOLT_OPER_INIT(&oper, device, reset, key);
312 err = bcmolt_oper_submit(dev_id, &oper.hdr);
313 if (err)
314 {
315 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to reset PON device(%d) failed, err = %s\n", dev, bcmos_strerror(err));
316 }else
317 {
318 OPENOLT_LOG(INFO, openolt_log_id, "Reset PON device(%d) success\n", dev);
319 }
320}
321
Shad Ansari627b5782018-08-13 22:49:32 +0000322Status Enable_(int argc, char *argv[]) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000323 bcmos_errno err;
324 bcmolt_host_init_parms init_parms = {};
325 init_parms.transport.type = BCM_HOST_API_CONN_LOCAL;
326 unsigned int failed_enable_device_cnt = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000327
Shad Ansariedef2132018-08-10 22:14:50 +0000328 if (!state.is_activated()) {
Shad Ansari627b5782018-08-13 22:49:32 +0000329
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500330 vendor_init();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000331 /* Initialize host subsystem */
332 err = bcmolt_host_init(&init_parms);
333 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500334 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to init OLT, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000335 return bcm_to_grpc_err(err, "Failed to init OLT");
336 }
337
338 bcmcli_session_parm mon_session_parm;
339 /* Create CLI session */
340 memset(&mon_session_parm, 0, sizeof(mon_session_parm));
341 mon_session_parm.get_prompt = openolt_cli_get_prompt_cb;
342 mon_session_parm.access_right = BCMCLI_ACCESS_ADMIN;
343 bcmos_errno rc = bcmcli_session_open(&mon_session_parm, &current_session);
344 BUG_ON(rc != BCM_ERR_OK);
345
346 /* API CLI */
347 bcm_openolt_api_cli_init(NULL, current_session);
348
349 /* Add quit command */
350 BCMCLI_MAKE_CMD_NOPARM(NULL, "quit", "Quit", bcm_cli_quit);
351
352 err = bcmolt_apiend_cli_init();
353 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500354 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to add apiend init, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000355 return bcm_to_grpc_err(err, "Failed to add apiend init");
356 }
357
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800358 bcmos_fastlock_init(&data_lock, 0);
Girish Gowdra252f4972020-09-07 21:24:01 -0700359 bcmos_fastlock_init(&acl_id_bitset_lock, 0);
360 bcmos_fastlock_init(&tm_sched_bitset_lock, 0);
361 bcmos_fastlock_init(&tm_qmp_bitset_lock, 0);
362 bcmos_fastlock_init(&flow_id_bitset_lock, 0);
363 bcmos_fastlock_init(&voltha_flow_to_device_flow_lock, 0);
Girish Gowdra96461052019-11-22 20:13:59 +0530364 bcmos_fastlock_init(&alloc_cfg_wait_lock, 0);
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +0530365 bcmos_fastlock_init(&gem_cfg_wait_lock, 0);
Girish Gowdra7a79dae2020-02-10 18:22:11 +0530366 bcmos_fastlock_init(&onu_deactivate_wait_lock, 0);
Girish Gowdra1935e6a2020-10-31 21:48:22 -0700367 bcmos_fastlock_init(&acl_packet_trap_handler_lock, 0);
Girish Gowdraeec0fc92021-05-12 15:37:55 -0700368 bcmos_fastlock_init(&symmetric_datapath_flow_id_lock, 0);
369 bcmos_fastlock_init(&pon_gem_to_onu_uni_map_lock, 0);
370
Girish Gowdra1935e6a2020-10-31 21:48:22 -0700371
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000372 OPENOLT_LOG(INFO, openolt_log_id, "Enable OLT - %s-%s\n", VENDOR_ID, MODEL_ID);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600373
Jason Huangbf45ffb2019-10-30 17:29:02 +0800374 //check BCM daemon is connected or not
375 Status status = check_connection();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000376 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800377 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000378 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800379 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000380 Status status = SubscribeIndication();
381 if (!status.ok()) {
382 OPENOLT_LOG(ERROR, openolt_log_id, "SubscribeIndication failed - %s : %s\n",
383 grpc_status_code_to_string(status.error_code()).c_str(),
384 status.error_message().c_str());
385 return status;
386 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800387
388 //check BAL state in initial stage
389 status = check_bal_ready();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000390 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800391 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000392 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800393 }
394
395 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000396 bcmos_errno err;
397 bcmolt_odid dev;
398 OPENOLT_LOG(INFO, openolt_log_id, "Enabling PON %d Devices ... \n", BCM_MAX_DEVS_PER_LINE_CARD);
399 for (dev = 0; dev < BCM_MAX_DEVS_PER_LINE_CARD; dev++) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400400 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000401 bcmolt_device_key dev_key = { };
402 dev_key.device_id = dev;
403 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
404 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
405 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
Jason Huangbf45ffb2019-10-30 17:29:02 +0800406 if (err == BCM_ERR_NOT_CONNECTED) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000407 bcmolt_device_key key = {.device_id = dev};
408 bcmolt_device_connect oper;
409 BCMOLT_OPER_INIT(&oper, device, connect, key);
Thiyagarajan Subramani3e8bfd92021-04-26 15:07:14 +0530410
411 /* BAL saves current state into dram_tune soc file and when dev_mgmt_daemon restarts
412 * it retains config from soc file. If openolt agent try to connect device without
413 * device reset device initialization fails hence doing device reset here. */
414 reset_pon_device(dev);
415
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000416 if (MODEL_ID == "asfvolt16") {
417 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
418 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_XGS__2_X);
419 } else if (MODEL_ID == "asgvolt64") {
420 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
421 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
422 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
Thiyagarajan Subramania2c2c5a2021-05-18 14:47:52 +0530423 } else if (MODEL_ID == "rlt-3200g-w") {
Thiyagarajan Subramani3e8bfd92021-04-26 15:07:14 +0530424 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_NONE);
425 if(dev == 1) {
426 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
427 }
428 BCMOLT_MSG_FIELD_SET (&oper, ras_ddr_mode, BCMOLT_RAS_DDR_USAGE_MODE_TWO_DDRS);
429 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
430 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000431 }
432 err = bcmolt_oper_submit(dev_id, &oper.hdr);
433 if (err) {
434 failed_enable_device_cnt ++;
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500435 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 +0000436 if (failed_enable_device_cnt == BCM_MAX_DEVS_PER_LINE_CARD) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500437 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 +0000438 return Status(grpc::StatusCode::INTERNAL, "Failed to activate all PON ports");
439 }
440 }
441 bcmos_usleep(200000);
442 }
443 else {
444 OPENOLT_LOG(WARNING, openolt_log_id, "PON deivce %d already connected\n", dev);
445 state.activate();
446 }
447 }
448 init_stats();
Shad Ansari627b5782018-08-13 22:49:32 +0000449 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000450 }
Shad Ansariedef2132018-08-10 22:14:50 +0000451
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000452 /* Start CLI */
453 OPENOLT_LOG(INFO, def_log_id, "Starting CLI\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400454 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000455 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400456}
457
458Status Disable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400459 //In the earlier implementation Disabling olt is done by disabling the NNI port associated with that.
460 //In inband scenario instead of using management interface to establish connection with adapter ,NNI interface will be used.
461 //Disabling NNI port on olt disable causes connection loss between adapter and agent.
462 //To overcome this disable is implemented by disabling all the PON ports
463 //associated with the device so as to support both in-band
464 //and out of band scenarios.
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400465
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400466 Status status;
467 int failedCount = 0;
Girish Gowdrae1db2952021-05-04 00:16:54 -0700468 OPENOLT_LOG(INFO, openolt_log_id, "Received disable OLT\n");
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400469 for (int i = 0; i < NumPonIf_(); i++) {
470 status = DisablePonIf_(i);
471 if (!status.ok()) {
472 failedCount+=1;
473 BCM_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", i);
474 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400475 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400476 if (failedCount == 0) {
477 state.deactivate();
Girish Gowdra252f4972020-09-07 21:24:01 -0700478 ::openolt::Indication ind;
479 ::openolt::OltIndication* olt_ind = new ::openolt::OltIndication;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400480 olt_ind->set_oper_state("down");
481 ind.set_allocated_olt_ind(olt_ind);
482 BCM_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
483 oltIndQ.push(ind);
484 return Status::OK;
485 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000486 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400487 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to disable olt ,all the PON ports are still in enabled state");
488 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400489
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400490 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 -0400491}
492
493Status Reenable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400494 Status status;
495 int failedCount = 0;
496 for (int i = 0; i < NumPonIf_(); i++) {
497 status = EnablePonIf_(i);
498 if (!status.ok()) {
499 failedCount+=1;
500 BCM_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", i);
501 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400502 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000503 if (failedCount == 0) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400504 state.activate();
Girish Gowdra252f4972020-09-07 21:24:01 -0700505 ::openolt::Indication ind;
506 ::openolt::OltIndication* olt_ind = new ::openolt::OltIndication;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400507 olt_ind->set_oper_state("up");
508 ind.set_allocated_olt_ind(olt_ind);
509 BCM_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
510 oltIndQ.push(ind);
511 return Status::OK;
512 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000513 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400514 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to re-enable olt ,all the PON ports are still in disabled state");
515 }
516 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 +0000517}
518
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000519inline uint64_t get_flow_status(uint16_t flow_id, uint16_t flow_type, uint16_t data_id) {
520 bcmos_errno err;
521 bcmolt_flow_key flow_key;
522 bcmolt_flow_cfg flow_cfg;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400523
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000524 flow_key.flow_id = flow_id;
525 flow_key.flow_type = (bcmolt_flow_type)flow_type;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400526
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000527 BCMOLT_CFG_INIT(&flow_cfg, flow, flow_key);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400528
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000529 switch (data_id) {
530 case ONU_ID: //onu_id
531 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, onu_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500532 #ifdef TEST_MODE
533 // It is impossible to mock the setting of flow_cfg.data.state because
534 // the actual bcmolt_cfg_get passes the address of flow_cfg.hdr and we cannot
535 // set the flow_cfg.data. So a new stub function is created and address
536 // of flow_cfg is passed. This is one-of case where we need to add test specific
537 // code in production code.
538 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
539 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000540 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500541 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000542 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500543 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get onu_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000544 return err;
545 }
546 return flow_cfg.data.onu_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400547 case FLOW_TYPE:
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500548 #ifdef TEST_MODE
549 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
550 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000551 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500552 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000553 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500554 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get flow_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000555 return err;
556 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400557 return flow_cfg.key.flow_type;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000558 case SVC_PORT_ID: //svc_port_id
559 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, svc_port_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500560 #ifdef TEST_MODE
561 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
562 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000563 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500564 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000565 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500566 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 +0000567 return err;
568 }
569 return flow_cfg.data.svc_port_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400570 case PRIORITY:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000571 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, priority);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500572 #ifdef TEST_MODE
573 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
574 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000575 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500576 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000577 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500578 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get priority, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000579 return err;
580 }
581 return flow_cfg.data.priority;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400582 case COOKIE: //cookie
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000583 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, cookie);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500584 #ifdef TEST_MODE
585 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
586 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000587 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500588 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000589 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500590 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get cookie, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000591 return err;
592 }
593 return flow_cfg.data.cookie;
594 case INGRESS_INTF_TYPE: //ingress intf_type
595 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500596 #ifdef TEST_MODE
597 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
598 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000599 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500600 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000601 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500602 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 +0000603 return err;
604 }
605 return flow_cfg.data.ingress_intf.intf_type;
606 case EGRESS_INTF_TYPE: //egress intf_type
607 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500608 #ifdef TEST_MODE
609 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
610 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000611 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500612 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000613 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500614 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 +0000615 return err;
616 }
617 return flow_cfg.data.egress_intf.intf_type;
618 case INGRESS_INTF_ID: //ingress intf_id
619 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500620 #ifdef TEST_MODE
621 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
622 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000623 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500624 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000625 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500626 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 +0000627 return err;
628 }
629 return flow_cfg.data.ingress_intf.intf_id;
630 case EGRESS_INTF_ID: //egress intf_id
631 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500632 #ifdef TEST_MODE
633 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
634 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000635 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500636 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000637 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500638 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 +0000639 return err;
640 }
641 return flow_cfg.data.egress_intf.intf_id;
642 case CLASSIFIER_O_VID:
643 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500644 #ifdef TEST_MODE
645 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
646 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000647 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500648 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000649 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500650 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 +0000651 return err;
652 }
653 return flow_cfg.data.classifier.o_vid;
654 case CLASSIFIER_O_PBITS:
655 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500656 #ifdef TEST_MODE
657 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
658 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000659 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500660 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000661 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500662 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 +0000663 return err;
664 }
665 return flow_cfg.data.classifier.o_pbits;
666 case CLASSIFIER_I_VID:
667 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500668 #ifdef TEST_MODE
669 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
670 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000671 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500672 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000673 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500674 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 +0000675 return err;
676 }
677 return flow_cfg.data.classifier.i_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400678 case CLASSIFIER_I_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000679 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500680 #ifdef TEST_MODE
681 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
682 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000683 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500684 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000685 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500686 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 +0000687 return err;
688 }
689 return flow_cfg.data.classifier.i_pbits;
690 case CLASSIFIER_ETHER_TYPE:
691 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500692 #ifdef TEST_MODE
693 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
694 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000695 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500696 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000697 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500698 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 +0000699 return err;
700 }
701 return flow_cfg.data.classifier.ether_type;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400702 case CLASSIFIER_IP_PROTO:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000703 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500704 #ifdef TEST_MODE
705 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
706 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000707 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500708 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000709 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500710 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 +0000711 return err;
712 }
713 return flow_cfg.data.classifier.ip_proto;
714 case CLASSIFIER_SRC_PORT:
715 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500716 #ifdef TEST_MODE
717 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
718 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000719 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500720 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000721 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500722 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 +0000723 return err;
724 }
725 return flow_cfg.data.classifier.src_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400726 case CLASSIFIER_DST_PORT:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000727 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500728 #ifdef TEST_MODE
729 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
730 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000731 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500732 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000733 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500734 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 +0000735 return err;
736 }
737 return flow_cfg.data.classifier.dst_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400738 case CLASSIFIER_PKT_TAG_TYPE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000739 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500740 #ifdef TEST_MODE
741 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
742 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000743 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500744 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000745 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500746 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 +0000747 return err;
748 }
749 return flow_cfg.data.classifier.pkt_tag_type;
750 case EGRESS_QOS_TYPE:
751 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500752 #ifdef TEST_MODE
753 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
754 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000755 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500756 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000757 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500758 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 +0000759 return err;
760 }
761 return flow_cfg.data.egress_qos.type;
762 case EGRESS_QOS_QUEUE_ID:
763 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500764 #ifdef TEST_MODE
765 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
766 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000767 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500768 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000769 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500770 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 +0000771 return err;
772 }
773 switch (flow_cfg.data.egress_qos.type) {
774 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE:
775 return flow_cfg.data.egress_qos.u.fixed_queue.queue_id;
776 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE:
777 return flow_cfg.data.egress_qos.u.tc_to_queue.tc_to_queue_id;
778 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC:
779 return flow_cfg.data.egress_qos.u.pbit_to_tc.tc_to_queue_id;
780 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE:
781 return flow_cfg.data.egress_qos.u.priority_to_queue.tm_q_set_id;
782 case BCMOLT_EGRESS_QOS_TYPE_NONE:
783 default:
784 return -1;
785 }
786 case EGRESS_QOS_TM_SCHED_ID:
787 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500788 #ifdef TEST_MODE
789 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
790 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000791 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500792 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000793 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500794 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 +0000795 return err;
796 }
797 return flow_cfg.data.egress_qos.tm_sched.id;
798 case ACTION_CMDS_BITMASK:
799 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500800 #ifdef TEST_MODE
801 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
802 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000803 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500804 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000805 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500806 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 +0000807 return err;
808 }
809 return flow_cfg.data.action.cmds_bitmask;
810 case ACTION_O_VID:
811 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500812 #ifdef TEST_MODE
813 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
814 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000815 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500816 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000817 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500818 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 +0000819 return err;
820 }
821 return flow_cfg.data.action.o_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400822 case ACTION_O_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000823 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500824 #ifdef TEST_MODE
825 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
826 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000827 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500828 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000829 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500830 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 +0000831 return err;
832 }
833 return flow_cfg.data.action.o_pbits;
834 case ACTION_I_VID:
835 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500836 #ifdef TEST_MODE
837 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
838 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000839 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500840 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000841 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500842 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 +0000843 return err;
844 }
845 return flow_cfg.data.action.i_vid;
846 case ACTION_I_PBITS:
847 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500848 #ifdef TEST_MODE
849 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
850 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000851 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500852 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000853 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500854 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 +0000855 return err;
856 }
857 return flow_cfg.data.action.i_pbits;
858 case STATE:
859 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, state);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500860 #ifdef TEST_MODE
861 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
862 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000863 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500864 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000865 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500866 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get state, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000867 return err;
868 }
869 return flow_cfg.data.state;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000870 case GROUP_ID:
871 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, group_id);
872 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
873 if (err) {
874 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get group_id, err = %s\n",bcmos_strerror(err));
875 return err;
876 }
877 return flow_cfg.data.group_id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000878 default:
879 return BCM_ERR_INTERNAL;
880 }
881
882 return err;
883}
884
885Status EnablePonIf_(uint32_t intf_id) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400886 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000887 bcmolt_pon_interface_cfg interface_obj;
888 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
889 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
890 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530891 bcmolt_status los_status;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000892
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530893 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000894 if (err == BCM_ERR_OK) {
895 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800896 OPENOLT_LOG(WARNING, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000897 return Status::OK;
898 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400899 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000900 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
901 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
902 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
903 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.interval, 5000);
904 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.onu_post_discovery_mode,
Girish Gowdra24297032020-03-23 12:32:37 -0700905 BCMOLT_ONU_POST_DISCOVERY_MODE_NONE);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000906 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.los, true);
907 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.onu_alarms, true);
908 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.tiwi, true);
909 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.ack_timeout, true);
910 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.sfi, true);
911 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.loki, true);
Burak Gurdag5e587792020-05-06 14:58:02 +0000912
913 // On GPON, power level mode is not set to its default value (i.e. 0) as documented in Broadcom documentation.
914 // Instead, it is set to 2 which means -6 dbM attenuation. Therefore, we explicitly set it to the default value below.
915 if (board_technology == "GPON") {
916 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.pls_maximum_allocation_size, BCMOLT_PON_POWER_LEVEL_PLS_MAXIMUM_ALLOCATION_SIZE_DEFAULT);
917 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.mode, BCMOLT_PON_POWER_LEVEL_MODE_DEFAULT);
918 }
919
kesavandc1f2db92020-08-31 15:32:06 +0530920 //Enable AES Encryption
921 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.key_exchange, BCMOLT_CONTROL_STATE_ENABLE);
922 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.authentication, BCMOLT_CONTROL_STATE_ENABLE);
923 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.fail_due_to_authentication_failure, BCMOLT_CONTROL_STATE_ENABLE);
924
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000925 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
926 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
927
928 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
929 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500930 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 +0000931 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
932 }
933 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
934 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500935 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 +0000936 return bcm_to_grpc_err(err, "Failed to enable PON interface");
937 }
938 else {
939 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
940 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
941 CreateDefaultSched(intf_id, downstream);
942 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400943 }
944
945 return Status::OK;
946}
947
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500948Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000949 bcmos_errno err;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400950 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000951 bcmolt_device_key dev_key = { };
952 bcmolt_olt_cfg olt_cfg = { };
953 bcmolt_olt_key olt_key = { };
954 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
955 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500956
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000957 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
958 topo.topology_maps.arr = &topo_map[0];
959 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
960 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
961 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400962 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000963 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400964 #ifdef TEST_MODE
965 // It is impossible to mock the setting of olt_cfg.data.bal_state because
966 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
967 // set the olt_cfg.data.topology. So a new stub function is created and address
968 // of olt_cfg is passed. This is one-of case where we need to test add specific
969 // code in production code.
970 err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
971 #else
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000972 err = bcmolt_cfg_get_mult_retry(dev_id, &olt_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400973 #endif
974 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500975 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 +0000976 return bcm_to_grpc_err(err, "cfg: Failed to query OLT topology");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500977 }
978
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000979 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
980 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500981
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400982 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
983 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000984 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500985
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000986 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
987 num_of_nni_ports,
988 num_of_pon_ports,
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400989 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500990
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000991 uint32_t num_failed_cfg_gets = 0;
Jason Huang09b73ea2020-01-08 17:52:05 +0800992 static std::string openolt_version = firmware_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000993 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
994 dev_key.device_id = devid;
995 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
996 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
997 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
998 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000999 err = bcmolt_cfg_get_mult_retry(dev_id, &dev_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001000 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001001 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 +00001002 num_failed_cfg_gets++;
1003 continue;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001004 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001005
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001006 std::string bal_version;
1007 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
1008 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
1009 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
Jason Huang09b73ea2020-01-08 17:52:05 +08001010 firmware_version = "BAL." + bal_version + "__" + openolt_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001011
1012 switch(dev_cfg.data.system_mode) {
1013 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
1014 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
1015 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
1016 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
1017 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
1018 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
1019 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
1020 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
1021 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
1022 case 20: board_technology = MIXED_TECH; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,MIXED_TECH); break;
1023 }
1024
1025 switch(dev_cfg.data.chip_family) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001026 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X: chip_family = "Maple"; break;
1027 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X: chip_family = "Aspen"; break;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001028 }
1029
Jason Huang09b73ea2020-01-08 17:52:05 +08001030 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s, family: %s, board_technology: %s\n",
1031 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 +00001032
1033 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001034 }
1035
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001036 /* 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 +00001037 only the devices that retured success*/
1038 if (num_failed_cfg_gets == BCM_MAX_DEVS_PER_LINE_CARD) {
1039 OPENOLT_LOG(ERROR, openolt_log_id, "device: Query of all the devices failed\n");
1040 return bcm_to_grpc_err(err, "device: All devices failed query");
1041 }
1042
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001043 return Status::OK;
1044}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001045
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001046Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001047 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001048 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
1049 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
1050 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001051
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001052 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001053 if (err == BCM_ERR_OK) {
1054 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001055 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001056 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1057 CreateDefaultSched(intf_id, upstream);
1058 CreateDefaultQueue(intf_id, upstream);
1059 return Status::OK;
1060 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1061 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
1062 return Status::OK;
1063 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001064 }
1065
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001066 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
1067 if (set_state) {
1068 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1069 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1070 } else {
1071 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1072 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1073 }
1074 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
1075 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001076 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err = %s\n",
1077 (set_state)?"enable":"disable", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001078 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
1079 }
1080 else {
1081 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
1082 if (set_state) {
1083 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1084 CreateDefaultSched(intf_id, upstream);
1085 CreateDefaultQueue(intf_id, upstream);
1086 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001087 }
1088
1089 return Status::OK;
1090}
1091
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001092Status DisablePonIf_(uint32_t intf_id) {
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001093 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001094 bcmolt_pon_interface_cfg interface_obj;
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001095 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1096 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001097
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001098 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
Girish Gowdrae1db2952021-05-04 00:16:54 -07001099 BCMOLT_MSG_FIELD_GET(&interface_obj, state);
1100
1101 err = bcmolt_cfg_get(dev_id, &interface_obj.hdr);
1102 if (err != BCM_ERR_OK) {
1103 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch pon port status, PON interface %d, err %d err_text=%s \n", intf_id, err, interface_obj.hdr.hdr.err_text);
1104 return bcm_to_grpc_err(err, "Failed to fetch pon port state");
1105 }
1106 if (interface_obj.data.state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1107 OPENOLT_LOG(INFO, openolt_log_id, "PON Interface already inactive, PON interface %d\n", intf_id);
1108 return Status::OK;
1109 }
1110
1111 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001112 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1113 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_DISABLE);
1114
1115 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1116 if (err != BCM_ERR_OK) {
1117 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable discovery of onu, PON interface %d, err %d\n", intf_id, err);
1118 return bcm_to_grpc_err(err, "Failed to disable discovery of onu");
1119 }
1120
1121 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1122 operation, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1123
1124 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1125 if (err != BCM_ERR_OK) {
1126 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 -04001127 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001128 }
1129
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001130 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled PON interface: %d\n", intf_id);
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001131 return Status::OK;
1132}
1133
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001134Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
kesavandc1f2db92020-08-31 15:32:06 +05301135 const char *vendor_id, const char *vendor_specific, uint32_t pir, bool omcc_encryption_mode) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001136 bcmos_errno err = BCM_ERR_OK;
1137 bcmolt_onu_cfg onu_cfg;
1138 bcmolt_onu_key onu_key;
1139 bcmolt_serial_number serial_number; /**< ONU serial number */
1140 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001141
Girish Gowdra24297032020-03-23 12:32:37 -07001142 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1143 bcmolt_onu_state onu_state;
1144
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001145 onu_key.onu_id = onu_id;
1146 onu_key.pon_ni = intf_id;
1147 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1148 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Girish Gowdra24297032020-03-23 12:32:37 -07001149#ifdef TEST_MODE
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001150 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1151 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1152 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1153 // of onu_cfg is passed. This is one-of case where we need to add test specific
1154 // code in production code.
1155 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Girish Gowdra24297032020-03-23 12:32:37 -07001156#else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001157 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Girish Gowdra24297032020-03-23 12:32:37 -07001158#endif
1159 OPENOLT_LOG(INFO, openolt_log_id, "Activate ONU : old state = %d, current state = %d\n",
1160 onu_cfg.data.onu_old_state, onu_cfg.data.onu_state);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001161 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001162 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) {
1163 OPENOLT_LOG(INFO, openolt_log_id, "ONU is already in ACTIVE state, \
1164not processing this request for pon_intf=%d onu_id=%d\n", intf_id, onu_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001165 return Status::OK;
Girish Gowdra24297032020-03-23 12:32:37 -07001166 } else if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_NOT_CONFIGURED &&
1167 onu_cfg.data.onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1168 // We need the ONU to be in NOT_CONFIGURED or INACTIVE state to further process the request
1169 OPENOLT_LOG(ERROR, openolt_log_id, "ONU in an invalid state to process the request, \
1170state=%d pon_intf=%d onu_id=%d\n", onu_cfg.data.onu_state, intf_id, onu_id);
1171 return bcm_to_grpc_err(err, "Failed to activate ONU, invalid ONU state");
1172 }
1173 } else {
1174 // This should never happen. BAL GET should succeed for non-existant ONUs too. The state of such ONUs will be NOT_CONFIGURED
1175 OPENOLT_LOG(ERROR, openolt_log_id, "ONU state query failed pon_intf=%d onu_id=%d\n", intf_id, onu_id);
1176 return bcm_to_grpc_err(err, "onu get failed");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001177 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001178
Girish Gowdra24297032020-03-23 12:32:37 -07001179 // If the ONU is not configured at all we need to first configure it
1180 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_NOT_CONFIGURED) {
1181 OPENOLT_LOG(INFO, openolt_log_id, "Configuring ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001182vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Girish Gowdra24297032020-03-23 12:32:37 -07001183 vendor_specific_to_str(vendor_specific).c_str(), pir);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001184
Girish Gowdra24297032020-03-23 12:32:37 -07001185 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1186 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1187 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1188 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1189 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1190 /*set burst and data profiles to fec disabled*/
1191 if (board_technology == "XGS-PON") {
1192 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1193 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1194 } else if (board_technology == "GPON") {
1195 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1196 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1197 }
1198 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1199 if (err != BCM_ERR_OK) {
1200 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to configure ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
1201 return bcm_to_grpc_err(err, "Failed to configure ONU");
1202 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001203 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001204
Burak Gurdaga0523592021-02-24 15:17:47 +00001205// TODO: MOVE THIS TO A NEW METHOD
kesavandc1f2db92020-08-31 15:32:06 +05301206 if (omcc_encryption_mode == true) {
1207 // set the encryption mode for omci port id
1208 bcmolt_itupon_gem_cfg gem_cfg;
1209 bcmolt_itupon_gem_key key = {};
1210 bcmolt_gem_port_configuration configuration = {};
1211 key.pon_ni = intf_id;
1212 key.gem_port_id = onu_id;
1213 bcmolt_control_state encryption_mode;
1214 encryption_mode = BCMOLT_CONTROL_STATE_ENABLE;
1215 BCMOLT_CFG_INIT(&gem_cfg, itupon_gem, key);
1216 BCMOLT_FIELD_SET(&gem_cfg.data, itupon_gem_cfg_data, encryption_mode, encryption_mode);
1217 err = bcmolt_cfg_set(dev_id, &gem_cfg.hdr);
1218 if(err != BCM_ERR_OK) {
Burak Gurdaga0523592021-02-24 15:17:47 +00001219 OPENOLT_LOG(ERROR, openolt_log_id, "failed to configure omci gem_port encryption mode = %d\n", onu_id);
kesavandc1f2db92020-08-31 15:32:06 +05301220 return bcm_to_grpc_err(err, "Access_Control set ITU PON OMCI Gem port failed");
1221 }
1222 }
Girish Gowdra24297032020-03-23 12:32:37 -07001223 // Now that the ONU is configured, move the ONU to ACTIVE state
1224 memset(&onu_cfg, 0, sizeof(bcmolt_onu_cfg));
1225 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1226 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1227 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
1228 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
1229 onu_state, BCMOLT_ONU_OPERATION_ACTIVE);
1230 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001231 if (err != BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001232 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 +00001233 return bcm_to_grpc_err(err, "Failed to activate ONU");
1234 }
Girish Gowdra24297032020-03-23 12:32:37 -07001235 // ONU will eventually get activated after we have submitted the operation request. The adapter will receive an asynchronous
1236 // ONU_ACTIVATION_COMPLETED_INDICATION
1237
1238 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 +00001239
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001240 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001241}
1242
Jonathan Davis70c21812018-07-19 15:32:10 -04001243Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1244 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001245 bcmos_errno err = BCM_ERR_OK;
1246 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1247 bcmolt_onu_cfg onu_cfg;
1248 bcmolt_onu_key onu_key; /**< Object key. */
1249 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001250
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001251 onu_key.onu_id = onu_id;
1252 onu_key.pon_ni = intf_id;
1253 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1254 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001255 #ifdef TEST_MODE
1256 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1257 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1258 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1259 // of onu_cfg is passed. This is one-of case where we need to add test specific
1260 // code in production code.
1261 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001262 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001263 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001264 #endif
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301265 onu_state = onu_cfg.data.onu_state;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001266 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001267 switch (onu_state) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001268 case BCMOLT_ONU_STATE_ACTIVE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001269 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001270 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001271 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1272 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1273 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001274 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 +00001275 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1276 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301277 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 +00001278 break;
1279 }
Jonathan Davis70c21812018-07-19 15:32:10 -04001280 }
1281
1282 return Status::OK;
1283}
1284
1285Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001286 const char *vendor_id, const char *vendor_specific) {
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301287 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301288 bcmolt_onu_state onu_state;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001289
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001290 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 -05001291 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1292
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001293 // Need to deactivate before removing it (BAL rules)
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001294 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301295
1296 err = get_onu_status((bcmolt_interface)intf_id, onu_id, &onu_state);
1297 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001298 if (onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1299 OPENOLT_LOG(INFO, openolt_log_id, "waiting for onu deactivate complete response: intf_id=%d, onu_id=%d\n",
1300 intf_id, onu_id);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301301 err = wait_for_onu_deactivate_complete(intf_id, onu_id);
1302 if (err) {
1303 OPENOLT_LOG(ERROR, openolt_log_id, "failed to delete onu intf_id %d, onu_id %d\n",
1304 intf_id, onu_id);
1305 return bcm_to_grpc_err(err, "Failed to delete ONU");
1306 }
1307 }
Girish Gowdra24297032020-03-23 12:32:37 -07001308 else {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301309 OPENOLT_LOG(INFO, openolt_log_id, "Onu is Inactive, onu_id: %d, not waiting for onu deactivate complete response\n",
1310 intf_id);
1311 }
1312 }
1313 else {
1314 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch Onu status, onu_id = %d, intf_id = %d, err = %s\n",
1315 onu_id, intf_id, bcmos_strerror(err));
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301316 return bcm_to_grpc_err(err, "Failed to delete ONU");
1317 }
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001318
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001319 bcmolt_onu_cfg cfg_obj;
1320 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001321
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001322 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 -04001323 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001324
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001325 key.onu_id = onu_id;
1326 key.pon_ni = intf_id;
1327 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001328
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301329 err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001330 if (err != BCM_ERR_OK)
1331 {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001332 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 -04001333 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1334 }
1335
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301336 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 +00001337 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001338}
1339
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001340#define MAX_CHAR_LENGTH 20
1341#define MAX_OMCI_MSG_LENGTH 44
1342Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001343 bcmolt_bin_str buf = {};
1344 bcmolt_onu_cpu_packets omci_cpu_packets;
1345 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001346
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001347 key.pon_ni = intf_id;
1348 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001349
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001350 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1351 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1352 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001353
1354 // ???
1355 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1356 buf.len = MAX_OMCI_MSG_LENGTH;
1357 } else {
1358 buf.len = pkt.size()/2;
1359 }
1360
1361 /* Send the OMCI packet using the BAL remote proxy API */
1362 uint16_t idx1 = 0;
1363 uint16_t idx2 = 0;
1364 uint8_t arraySend[buf.len];
1365 char str1[MAX_CHAR_LENGTH];
1366 char str2[MAX_CHAR_LENGTH];
1367 memset(&arraySend, 0, buf.len);
1368
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001369 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1370 sprintf(str1,"%c", pkt[idx1]);
1371 sprintf(str2,"%c", pkt[++idx1]);
1372 strcat(str1,str2);
1373 arraySend[idx2] = strtol(str1, NULL, 16);
1374 }
1375
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001376 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1377 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001378
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001379 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1380 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1381 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001382
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001383 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001384 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001385 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 +00001386 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001387 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001388 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 -05001389 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001390 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001391 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001392
1393 return Status::OK;
1394}
1395
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001396Status 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 +00001397 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1398 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1399 bcmolt_bin_str buf = {};
1400 bcmolt_gem_port_id gem_port_id_array[1];
1401 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001402
Craig Lutgen967a1d02018-11-27 10:41:51 -06001403 if (port_no > 0) {
1404 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001405 if (gemport_id == 0) {
1406 bcmos_fastlock_lock(&data_lock);
1407 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1408 // Pick any flow that is mapped with the same port_no.
1409 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1410 if (it != port_to_flows.end() && !it->second.empty()) {
1411 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1412 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1413 if (fit != flowid_to_gemport.end()) {
1414 found = true;
1415 gemport_id = fit->second;
1416 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001417 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001418 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001419
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001420 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001421 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 -08001422 onu_id, port_no, intf_id);
1423 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1424 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001425 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 -08001426 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001427 }
1428
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001429 gem_port_id_array[0] = gemport_id;
1430 gem_port_list.len = 1;
1431 gem_port_list.arr = gem_port_id_array;
1432 buf.len = pkt.size();
1433 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1434 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1435
1436 /* init the API struct */
1437 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1438 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1439 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1440 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1441 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1442
1443 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1444 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1445
1446 /* call API */
1447 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001448 }
1449 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001450 //TODO: Port No is 0, it is coming sender requirement.
1451 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1452 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001453 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001454 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001455
1456 return Status::OK;
1457}
1458
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001459Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001460 bcmolt_flow_key key = {}; /* declare key */
1461 bcmolt_bin_str buffer = {};
1462 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001463
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001464 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
Girish Gowdra252f4972020-09-07 21:24:01 -07001465 bcmolt_flow_id flow_id = INVALID_FLOW_ID;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001466
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001467 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1468 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1469 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1470 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1471 key.flow_id = flow_id;
1472 else {
Jason Huang09b73ea2020-01-08 17:52:05 +08001473 if (flow_id_counters) {
1474 std::map<flow_pair, int>::iterator it;
1475 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1476 int flow_index = it->first.first;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001477 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1478 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1479 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1480 key.flow_id = flow_index;
1481 break;
1482 }
1483 }
1484 }
1485 else {
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001486 OPENOLT_LOG(ERROR, openolt_log_id, "no flow id found for uplink packetout\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001487 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1488 }
1489 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001490
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001491 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001492
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001493 /* Initialize the API struct. */
1494 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001495
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001496 buffer.len = pkt.size();
1497 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1498 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1499 if (buffer.arr == NULL) {
1500 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1501 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1502 }
1503 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1504
1505 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1506 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001507 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 -05001508 return bcm_to_grpc_err(BCM_ERR_SYSCALL_ERR, "Error sending packets via nni port");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001509 } else {
1510 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1511 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001512
1513 return Status::OK;
1514}
Girish Gowdra252f4972020-09-07 21:24:01 -07001515
Burak Gurdaga0523592021-02-24 15:17:47 +00001516bool get_aes_flag_for_gem_port(const google::protobuf::Map<unsigned int, bool> &gemport_to_aes, uint32_t gemport_id) {
1517 bool aes_flag = false;
1518 for (google::protobuf::Map<unsigned int, bool>::const_iterator it=gemport_to_aes.begin(); it!=gemport_to_aes.end(); it++) {
1519 if (it->first == gemport_id) {
1520 aes_flag = it->second;
1521 break;
1522 }
1523 }
1524 return aes_flag;
1525}
1526
Girish Gowdra252f4972020-09-07 21:24:01 -07001527Status FlowAddWrapper_(const ::openolt::Flow* request) {
1528
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001529 Status st = Status::OK;
Girish Gowdra252f4972020-09-07 21:24:01 -07001530 int32_t access_intf_id = request->access_intf_id();
1531 int32_t onu_id = request->onu_id();
1532 int32_t uni_id = request->uni_id();
1533 uint32_t port_no = request->port_no();
1534 uint64_t voltha_flow_id = request->flow_id();
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001535 uint64_t symmetric_voltha_flow_id = 0;
Girish Gowdra252f4972020-09-07 21:24:01 -07001536 const std::string flow_type = request->flow_type();
1537 int32_t alloc_id = request->alloc_id();
1538 int32_t network_intf_id = request->network_intf_id();
1539 int32_t gemport_id = request->gemport_id();
1540 const ::openolt::Classifier& classifier = request->classifier();
1541 const ::openolt::Action& action = request->action();
1542 int32_t priority = request->priority();
1543 uint64_t cookie = request->cookie();
1544 int32_t group_id = request->group_id();
1545 uint32_t tech_profile_id = request->tech_profile_id();
1546 bool replicate_flow = request->replicate_flow();
1547 const google::protobuf::Map<unsigned int, unsigned int> &pbit_to_gemport = request->pbit_to_gemport();
Burak Gurdaga0523592021-02-24 15:17:47 +00001548 const google::protobuf::Map<unsigned int, bool> &gemport_to_aes = request->gemport_to_aes();
Girish Gowdra252f4972020-09-07 21:24:01 -07001549 uint16_t flow_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001550 bool enable_encryption;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001551 // When following conditions are ALL met, it qualifies as datapath flow.
1552 // 1. valid access_intf_id, onu_id, uni_id
1553 // 2. Valid tech_profile_id
1554 // 3. flow_type that is not MULTICAST
1555 // 4. Not a trap-to-host flow.
1556 bool datapathFlow = access_intf_id >= 0 && onu_id >= 0 && uni_id >= 0 && tech_profile_id > 0
1557 && flow_type != multicast && !action.cmd().trap_to_host();
1558
1559 if (datapathFlow) {
1560 const std::string inverse_flow_type = flow_type.compare(upstream) == 0 ? downstream : upstream;
1561 symmetric_datapath_flow_id_map_key key(access_intf_id, onu_id, uni_id, tech_profile_id, inverse_flow_type);
1562 // Find the onu-uni mapping for the pon-gem key
1563 bcmos_fastlock_lock(&symmetric_datapath_flow_id_lock);
1564 auto it = symmetric_datapath_flow_id_map.find(key);
1565 bcmos_fastlock_unlock(&symmetric_datapath_flow_id_lock, 0);
1566 if (it != symmetric_datapath_flow_id_map.end()) {
1567 symmetric_voltha_flow_id = it->second;
1568 }
1569 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001570
1571 // The intf_id variable defaults to access(PON) interface ID.
1572 // For trap-from-nni flow where access interface ID is not valid , change it to NNI interface ID
1573 // This intf_id identifies the pool from which we get the flow_id
1574 uint32_t intf_id = access_intf_id;
1575 if (onu_id < 1) {
1576 onu_id = 1;
1577 }
1578 if (access_intf_id < 0) {
1579 intf_id = network_intf_id;
1580 }
1581
1582 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)
1583 // This is the case of voltha_flow_id (not symmetric_voltha_flow_id)
1584 if (is_voltha_flow_installed(voltha_flow_id)) {
1585 OPENOLT_LOG(INFO, openolt_log_id, "voltha_flow_id=%lu, already installed\n", voltha_flow_id);
1586 return ::Status(grpc::StatusCode::ALREADY_EXISTS, "voltha-flow-already-installed");
1587 }
1588
Girish Gowdra252f4972020-09-07 21:24:01 -07001589 // This is the case of symmetric_voltha_flow_id
1590 // If symmetric_voltha_flow_id is available and valid in the Flow message,
1591 // check if it is installed, and use the corresponding device_flow_id
1592 if (symmetric_voltha_flow_id > 0 && is_voltha_flow_installed(symmetric_voltha_flow_id)) { // symmetric flow found
1593 OPENOLT_LOG(INFO, openolt_log_id, "symmetric flow and the symmetric flow is installed\n");
1594 const device_flow_params *dev_fl_symm_params;
1595 dev_fl_symm_params = get_device_flow_params(symmetric_voltha_flow_id);
1596 if (dev_fl_symm_params == NULL) {
1597 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)
1598 return ::Status(grpc::StatusCode::INTERNAL, "symmetric-flow-details-not-found");
1599 }
1600
1601 if (!replicate_flow) { // No flow replication
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001602 flow_id = dev_fl_symm_params[0].flow_id;
1603 gemport_id = dev_fl_symm_params[0].gemport_id; // overwrite the gemport with symmetric flow gemport
1604 // Should be same as what is coming in this request.
1605 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
1606 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1607 cl.set_o_pbits(dev_fl_symm_params[0].pbit);
1608 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1609 flow_type, alloc_id, network_intf_id, gemport_id, cl,
1610 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
1611 if (st.error_code() != grpc::StatusCode::OK && st.error_code() != grpc::StatusCode::ALREADY_EXISTS) {
1612 OPENOLT_LOG(ERROR, openolt_log_id, "failed to install device flow=%u for voltha flow=%lu", flow_id, voltha_flow_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001613 return st;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001614 }
1615
1616 device_flow dev_fl;
1617 dev_fl.is_flow_replicated = false;
1618 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1619 dev_fl.voltha_flow_id = voltha_flow_id;
1620 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params));
1621 // update voltha flow to cache
1622 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
Girish Gowdra252f4972020-09-07 21:24:01 -07001623 } else { // Flow to be replicated
1624 OPENOLT_LOG(INFO, openolt_log_id,"symmetric flow and replication is needed\n");
1625 for (uint8_t i=0; i<NUMBER_OF_REPLICATED_FLOWS; i++) {
1626 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1627 flow_id = dev_fl_symm_params[i].flow_id;
1628 gemport_id = dev_fl_symm_params[i].gemport_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001629 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001630 cl.set_o_pbits(dev_fl_symm_params[i].pbit);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001631 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdrade65ab42020-12-17 23:08:43 -08001632 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001633 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001634 if (st.error_code() != grpc::StatusCode::OK && st.error_code() != grpc::StatusCode::ALREADY_EXISTS) {
1635 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);
1636 // On failure remove any successfully replicated flows installed so far for the voltha_flow_id
1637 if (i > 0) {
1638 for (int8_t j = i-1; j >= 0; j--) {
1639 flow_id = dev_fl_symm_params[j].flow_id;
1640 FlowRemove_(flow_id, flow_type);
1641 }
1642 }
1643 return st;
1644 }
1645 }
1646 device_flow dev_fl;
1647 dev_fl.is_flow_replicated = true;
1648 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1649 dev_fl.voltha_flow_id = voltha_flow_id;
1650 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params)*NUMBER_OF_REPLICATED_FLOWS);
1651 // update voltha flow to cache
1652 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1653 }
1654 } else { // No symmetric flow found
1655 if (!replicate_flow) { // No flow replication
1656 OPENOLT_LOG(INFO, openolt_log_id, "not a symmetric flow and replication is not needed\n");
1657 flow_id = get_flow_id();
1658 if (flow_id == INVALID_FLOW_ID) {
1659 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocated flow id for voltha-flow-id=%lu\n", voltha_flow_id);
1660 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1661 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001662 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001663 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001664 flow_type, alloc_id, network_intf_id, gemport_id, classifier,
Burak Gurdaga0523592021-02-24 15:17:47 +00001665 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001666 if (st.error_code() == grpc::StatusCode::OK) {
1667 device_flow dev_fl;
1668 dev_fl.is_flow_replicated = false;
1669 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // Invalid
1670 dev_fl.voltha_flow_id = voltha_flow_id;
1671 dev_fl.params[0].flow_id = flow_id;
1672 dev_fl.params[0].gemport_id = gemport_id;
1673 dev_fl.params[0].pbit = classifier.o_pbits();
1674 // update voltha flow to cache
1675 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1676 } else {
1677 // Free the flow id on failure
1678 free_flow_id(flow_id);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001679 return st;
Girish Gowdra252f4972020-09-07 21:24:01 -07001680 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001681 } else { // Flow to be replicated
1682 OPENOLT_LOG(INFO, openolt_log_id,"not a symmetric flow and replication is needed\n");
1683 if (pbit_to_gemport.size() != NUMBER_OF_PBITS) {
1684 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pbit-to-gemport map size=%lu", pbit_to_gemport.size())
1685 return ::Status(grpc::StatusCode::OUT_OF_RANGE, "pbit-to-gemport-map-len-invalid-for-flow-replication");
1686 }
1687 uint16_t flow_ids[NUMBER_OF_REPLICATED_FLOWS];
1688 device_flow dev_fl;
1689 if (get_flow_ids(NUMBER_OF_REPLICATED_FLOWS, flow_ids)) {
1690 uint8_t cnt = 0;
1691 dev_fl.is_flow_replicated = true;
1692 dev_fl.voltha_flow_id = voltha_flow_id;
1693 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // invalid
1694 for (google::protobuf::Map<unsigned int, unsigned int>::const_iterator it=pbit_to_gemport.begin(); it!=pbit_to_gemport.end(); it++) {
1695 dev_fl.params[cnt].flow_id = flow_ids[cnt];
1696 dev_fl.params[cnt].pbit = it->first;
1697 dev_fl.params[cnt].gemport_id = it->second;
1698
1699 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1700 flow_id = dev_fl.params[cnt].flow_id;
1701 gemport_id = dev_fl.params[cnt].gemport_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001702 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001703 cl.set_o_pbits(dev_fl.params[cnt].pbit);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001704 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001705 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001706 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001707 if (st.error_code() != grpc::StatusCode::OK) {
1708 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);
1709 // Remove any successfully replicated flows installed so far for the voltha_flow_id
1710 if (cnt > 0) {
1711 for (int8_t j = cnt-1; j >= 0; j--) {
1712 flow_id = dev_fl.params[j].flow_id;
1713 FlowRemove_(flow_id, flow_type);
1714 }
1715 }
1716 // Free up all the flow IDs on failure
1717 free_flow_ids(NUMBER_OF_REPLICATED_FLOWS, flow_ids);
1718 return st;
1719 }
1720 cnt++;
1721 }
1722 // On successful flow replication update voltha-flow-id to device-flow map to cache
1723 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1724 } else {
1725 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocate flow ids for replication voltha-flow-id=%lu\n", voltha_flow_id);
1726 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1727 }
1728 }
1729 }
1730
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001731 if (datapathFlow) {
1732 // Create the pon-gem to onu-uni mapping
1733 symmetric_datapath_flow_id_map_key key(access_intf_id, onu_id, uni_id, tech_profile_id, flow_type);
1734 bcmos_fastlock_lock(&symmetric_datapath_flow_id_lock);
1735 symmetric_datapath_flow_id_map[key] = voltha_flow_id;
1736 bcmos_fastlock_unlock(&symmetric_datapath_flow_id_lock, 0);
1737 }
1738
1739 return st;
Girish Gowdra252f4972020-09-07 21:24:01 -07001740}
1741
1742
Craig Lutgen967a1d02018-11-27 10:41:51 -06001743Status 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 +00001744 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001745 int32_t alloc_id, int32_t network_intf_id,
1746 int32_t gemport_id, const ::openolt::Classifier& classifier,
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001747 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie,
Burak Gurdaga0523592021-02-24 15:17:47 +00001748 int32_t group_id, uint32_t tech_profile_id, bool aes_enabled) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001749 bcmolt_flow_cfg cfg;
1750 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001751 int32_t o_vid = -1;
1752 bool single_tag = false;
1753 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001754 bcmolt_classifier c_val = { };
1755 bcmolt_action a_val = { };
1756 bcmolt_tm_queue_ref tm_val = { };
1757 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05001758 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001759
Jason Huang09b73ea2020-01-08 17:52:05 +08001760 OPENOLT_LOG(INFO, openolt_log_id, "flow add received for flow_id=%u, flow_type=%s\n", flow_id, flow_type.c_str());
1761
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001762 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001763 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001764 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001765 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001766 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001767 } else if (flow_type.compare(multicast) == 0) {
1768 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001769 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001770 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001771 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001772 }
1773
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001774 BCMOLT_CFG_INIT(&cfg, flow, key);
1775 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001776
Jason Huang09b73ea2020-01-08 17:52:05 +08001777 if (action.cmd().trap_to_host()) {
Girish Gowdra1935e6a2020-10-31 21:48:22 -07001778 Status resp = handle_acl_rule_install(onu_id, flow_id, gemport_id, flow_type, access_intf_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001779 network_intf_id, classifier);
Jason Huang09b73ea2020-01-08 17:52:05 +08001780 return resp;
1781 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001782
1783 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1784
1785 if (access_intf_id >= 0 && network_intf_id >= 0) {
1786 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1787 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1788 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08001789 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1790 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001791 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1792 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1793 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1794 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1795 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001796 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001797 } else {
1798 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
1799 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001800 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001801
Burak Gurdaga0523592021-02-24 15:17:47 +00001802 if (onu_id >= ONU_ID_START) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001803 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
1804 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001805 if (gemport_id >= GEM_PORT_ID_START) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001806 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
1807 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001808 if (gemport_id >= GEM_PORT_ID_START && port_no != 0) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001809 bcmos_fastlock_lock(&data_lock);
1810 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
1811 port_to_flows[port_no].insert(key.flow_id);
1812 flowid_to_gemport[key.flow_id] = gemport_id;
1813 }
1814 else
1815 {
1816 flowid_to_port[key.flow_id] = port_no;
1817 }
1818 bcmos_fastlock_unlock(&data_lock, 0);
1819 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001820
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001821 if (priority_value >= 0) {
1822 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
1823 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301824
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001825 } else { // MULTICAST FLOW
1826 if (group_id >= 0) {
1827 BCMOLT_MSG_FIELD_SET(&cfg, group_id, group_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001828 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001829 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1830 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001831 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001832
1833 {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001834 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001835 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001836 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
1837 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001838 }
1839
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001840 if (classifier.dst_mac().size() > 0) {
1841 bcmos_mac_address d_mac = {};
1842 bcmos_mac_address_init(&d_mac);
1843 memcpy(d_mac.u8, classifier.dst_mac().data(), sizeof(d_mac.u8));
1844 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_mac %02x:%02x:%02x:%02x:%02x:%02x\n", d_mac.u8[0],
1845 d_mac.u8[1], d_mac.u8[2], d_mac.u8[3], d_mac.u8[4], d_mac.u8[5]);
1846 BCMOLT_FIELD_SET(&c_val, classifier, dst_mac, d_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001847 }
1848
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001849 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001850 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001851 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001852 }
1853 */
1854
1855 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001856 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
1857 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001858 }
1859
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001860 if (classifier.dst_ip()) {
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08001861 bcmos_ipv4_address d_ip = {};
1862 bcmos_ipv4_address_init(&d_ip);
1863 d_ip.u32 = classifier.dst_ip();
1864 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_ip %04x\n", d_ip.u32);
1865 BCMOLT_FIELD_SET(&c_val, classifier, dst_ip, d_ip);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001866 }
1867
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08001868 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001869 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001870 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001871 }
1872 */
1873
1874 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001875 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
1876 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001877 }
1878
1879 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001880 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
1881 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001882 }
1883
1884 if (!classifier.pkt_tag_type().empty()) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001885 if (classifier.o_vid()) {
1886 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
1887 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
1888 }
1889
1890 if (classifier.i_vid()) {
1891 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
1892 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
1893 }
1894
1895 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
1896 if (classifier.pkt_tag_type().compare("untagged") == 0) {
1897 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
1898 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
1899 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
1900 single_tag = true;
1901
1902 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301903 // OpenOlt adapter will send 0xFF in case of no pbit classification
1904 // If it is any other value (0 to 7), it is for outer pbit classification.
1905 // OpenFlow protocol does not provide inner pbit classification (in case of double tagged packets),
1906 // and VOLTHA has not used any workaround to solve this problem (for ex: use metadata field).
1907 // Also there exists no use case for i-pbit classification, so we can safely ignore this for now.
1908 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001909 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301910 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001911 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
1912 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001913
Jason Huang09b73ea2020-01-08 17:52:05 +08001914 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301915 // Same comments as in case of "single_tag" packets.
1916 // 0xFF means no pbit classification, otherwise a valid PCP (0 to 7).
1917 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001918 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301919 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001920 }
1921 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001922 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001923 }
1924
Jason Huang09b73ea2020-01-08 17:52:05 +08001925 const ::openolt::ActionCmd& cmd = action.cmd();
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001926
Jason Huang09b73ea2020-01-08 17:52:05 +08001927 if (cmd.add_outer_tag()) {
1928 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
1929 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001930 }
1931
Jason Huang09b73ea2020-01-08 17:52:05 +08001932 if (cmd.remove_outer_tag()) {
1933 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
1934 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
1935 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301936
Jason Huang09b73ea2020-01-08 17:52:05 +08001937 if (action.o_vid()) {
1938 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
1939 o_vid = action.o_vid();
1940 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
1941 }
1942
1943 if (action.o_pbits()) {
1944 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
1945 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
1946 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301947
Jason Huang09b73ea2020-01-08 17:52:05 +08001948 if (action.i_vid()) {
1949 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
1950 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
1951 }
1952
1953 if (action.i_pbits()) {
1954 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
1955 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
1956 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301957
Jason Huang09b73ea2020-01-08 17:52:05 +08001958 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
1959
Burak Gurdaga0523592021-02-24 15:17:47 +00001960 if ((access_intf_id >= 0) && (onu_id >= ONU_ID_START)) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001961 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
1962 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00001963 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 +00001964
Jason Huang09b73ea2020-01-08 17:52:05 +08001965 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1966 // Queue 0 on DS subscriber scheduler
1967 tm_val.queue_id = 0;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001968
Jason Huang09b73ea2020-01-08 17:52:05 +08001969 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1970 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1971 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001972
Jason Huang09b73ea2020-01-08 17:52:05 +08001973 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1974 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1975 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001976
Jason Huang09b73ea2020-01-08 17:52:05 +08001977 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1978 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
1979 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 +00001980
Jason Huang09b73ea2020-01-08 17:52:05 +08001981 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1982 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1983 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1984 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 +00001985
Jason Huang09b73ea2020-01-08 17:52:05 +08001986 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
1987 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1988 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1989 }
1990 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
1991 // NNI Scheduler ID
1992 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1993 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1994 // Queue 0 on NNI scheduler
1995 tm_val.queue_id = 0;
1996 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1997 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1998 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001999
Jason Huang09b73ea2020-01-08 17:52:05 +08002000 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 +00002001 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2002 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2003
Jason Huang09b73ea2020-01-08 17:52:05 +08002004 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2005 /* Fetch TM QMP ID mapped to US NNI scheduler */
2006 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2007 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2008 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2009 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2010 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 +00002011
Jason Huang09b73ea2020-01-08 17:52:05 +08002012 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 +00002013 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2014 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002015 }
Shad Ansari39739bc2018-09-13 21:38:37 +00002016 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302017 } else {
2018 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2019 tm_val.queue_id = 0;
2020
2021 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2022 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2023 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2024
2025 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2026 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
2027 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00002028 }
2029
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002030 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002031
Girish Gowdra252f4972020-09-07 21:24:01 -07002032#ifndef SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002033 // BAL 3.1 supports statistics only for unicast flows.
2034 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
2035 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
2036 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002037#endif // SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002038
Girish Gowdra252f4972020-09-07 21:24:01 -07002039#ifndef SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002040#ifdef FLOW_CHECKER
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002041 //Flow Checker, To avoid duplicate flow.
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002042 if (flow_id_counters != 0) {
2043 bool b_duplicate_flow = false;
Jason Huang09b73ea2020-01-08 17:52:05 +08002044 std::map<flow_pair, int>::iterator it;
2045
2046 for(it = flow_map.begin(); it != flow_map.end(); it++) {
2047 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(it->first.first, it->first.second, ONU_ID)) && \
2048 (key.flow_type == it->first.second) && \
2049 (cfg.data.svc_port_id == get_flow_status(it->first.first, it->first.second, SVC_PORT_ID)) && \
2050 (cfg.data.priority == get_flow_status(it->first.first, it->first.second, PRIORITY)) && \
2051 (cfg.data.cookie == get_flow_status(it->first.first, it->first.second, COOKIE)) && \
2052 (cfg.data.ingress_intf.intf_type == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_TYPE)) && \
2053 (cfg.data.ingress_intf.intf_id == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_ID)) && \
2054 (cfg.data.egress_intf.intf_type == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_TYPE)) && \
2055 (cfg.data.egress_intf.intf_id == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_ID)) && \
2056 (c_val.o_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_VID)) && \
2057 (c_val.o_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_PBITS)) && \
2058 (c_val.i_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_VID)) && \
2059 (c_val.i_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_PBITS)) && \
2060 (c_val.ether_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_ETHER_TYPE)) && \
2061 (c_val.ip_proto == get_flow_status(it->first.first, it->first.second, CLASSIFIER_IP_PROTO)) && \
2062 (c_val.src_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_SRC_PORT)) && \
2063 (c_val.dst_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_DST_PORT)) && \
2064 (c_val.pkt_tag_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_PKT_TAG_TYPE)) && \
2065 (cfg.data.egress_qos.type == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TYPE)) && \
2066 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_QUEUE_ID)) && \
2067 (cfg.data.egress_qos.tm_sched.id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TM_SCHED_ID)) && \
2068 (a_val.cmds_bitmask == get_flow_status(it->first.first, it->first.second, ACTION_CMDS_BITMASK)) && \
2069 (a_val.o_vid == get_flow_status(it->first.first, it->first.second, ACTION_O_VID)) && \
2070 (a_val.i_vid == get_flow_status(it->first.first, it->first.second, ACTION_I_VID)) && \
2071 (a_val.o_pbits == get_flow_status(it->first.first, it->first.second, ACTION_O_PBITS)) && \
2072 (a_val.i_pbits == get_flow_status(it->first.first, it->first.second, ACTION_I_PBITS)) && \
2073 (cfg.data.state == get_flow_status(it->first.first, it->first.second, STATE)) && \
2074 (cfg.data.group_id == get_flow_status(it->first.first, it->first.second, GROUP_ID));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002075#ifdef SHOW_FLOW_PARAM
2076 // Flow Parameter
2077 FLOW_PARAM_LOG();
2078#endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002079 if (b_duplicate_flow) {
2080 FLOW_LOG(WARNING, "Flow duplicate", 0);
2081 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
2082 }
2083 }
2084 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002085#endif // FLOW_CHECKER
2086#endif // SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002087
2088 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2089 if (err) {
2090 FLOW_LOG(ERROR, "Flow add failed", err);
2091 return bcm_to_grpc_err(err, "flow add failed");
2092 } else {
2093 FLOW_LOG(INFO, "Flow add ok", err);
2094 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002095 flow_map[std::pair<int, int>(key.flow_id,key.flow_type)] = flow_map.size();
2096 flow_id_counters = flow_map.size();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002097 bcmos_fastlock_unlock(&data_lock, 0);
Girish Gowdra252f4972020-09-07 21:24:01 -07002098
2099 }
Burak Gurdaga0523592021-02-24 15:17:47 +00002100
2101 /*
2102 Enable AES encryption on GEM ports if they are used in downstream unicast flows.
2103 Rationale: We can't do upstream encryption in GPON. This change addresses the common denominator (and also minimum viable)
2104 use case for both technologies which is downstream unicast GEM port encryption. Since the downstream traffic is inherently
2105 broadcast to all the ONUs behind a PON port, encrypting the individual subscriber traffic in this direction is important
2106 and considered good enough in terms of security (See Section 12.1 of G.984.3). For upstream unicast and downstream multicast
2107 GEM encryption, we need to make additional changes specific to XGSPON. This will be done as a future work.
2108 */
2109 if (aes_enabled && (access_intf_id >= 0) && (gemport_id >= GEM_PORT_ID_START) && (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM)) {
2110 OPENOLT_LOG(INFO, openolt_log_id, "Setting encryption on pon = %d gem_port = %d through flow_id = %d\n", access_intf_id, gemport_id, flow_id);
Thiyagarajan Subramani19168f52021-05-25 23:26:41 +05302111 enable_encryption_for_gem_port(access_intf_id, gemport_id, board_technology);
Burak Gurdaga0523592021-02-24 15:17:47 +00002112 } else {
2113 OPENOLT_LOG(WARNING, openolt_log_id, "Flow config for flow_id = %d is not suitable for setting downstream encryption on pon = %d gem_port = %d. No action taken.\n", flow_id, access_intf_id, gemport_id);
2114 }
2115
Girish Gowdra252f4972020-09-07 21:24:01 -07002116 return Status::OK;
2117}
2118
2119Status FlowRemoveWrapper_(const ::openolt::Flow* request) {
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002120 int32_t access_intf_id = request->access_intf_id();
2121 int32_t onu_id = request->onu_id();
2122 int32_t uni_id = request->uni_id();
2123 uint32_t tech_profile_id = request->tech_profile_id();
Girish Gowdra252f4972020-09-07 21:24:01 -07002124 const std::string flow_type = request->flow_type();
2125 uint64_t voltha_flow_id = request->flow_id();
2126 Status st;
2127
2128 // If Voltha flow is not installed, return fail
2129 if (! is_voltha_flow_installed(voltha_flow_id)) {
2130 OPENOLT_LOG(ERROR, openolt_log_id, "voltha_flow_id=%lu not found\n", voltha_flow_id);
2131 return ::Status(grpc::StatusCode::NOT_FOUND, "voltha-flow-not-found");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002132 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04002133
Girish Gowdra252f4972020-09-07 21:24:01 -07002134 const device_flow *dev_fl = get_device_flow(voltha_flow_id);
2135 if (dev_fl == NULL) {
2136 OPENOLT_LOG(ERROR, openolt_log_id, "device flow for voltha_flow_id=%lu in the cache is NULL\n", voltha_flow_id);
2137 return ::Status(grpc::StatusCode::INTERNAL, "device-flow-null-in-cache");
2138 }
2139 if (dev_fl->is_flow_replicated) {
2140 // Note: Here we are ignoring FlowRemove failures
2141 for (int i=0; i<NUMBER_OF_REPLICATED_FLOWS; i++) {
2142 st = FlowRemove_(dev_fl->params[i].flow_id, flow_type);
2143 if (st.error_code() == grpc::StatusCode::OK) {
2144 free_flow_id(dev_fl->params[i].flow_id);
2145 }
2146 }
2147 } else {
2148 // Note: Here we are ignoring FlowRemove failures
2149 st = FlowRemove_(dev_fl->params[0].flow_id, flow_type);
2150 if (st.error_code() == grpc::StatusCode::OK) {
2151 free_flow_id(dev_fl->params[0].flow_id);
2152 }
2153 }
2154 // remove the flow from cache on voltha flow removal
2155 remove_voltha_flow_from_cache(voltha_flow_id);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002156
2157 symmetric_datapath_flow_id_map_key key(access_intf_id, onu_id, uni_id, tech_profile_id, flow_type);
2158 // Remove onu-uni mapping for the pon-gem key
2159 bcmos_fastlock_lock(&symmetric_datapath_flow_id_lock);
2160 symmetric_datapath_flow_id_map.erase(key);
2161 bcmos_fastlock_unlock(&symmetric_datapath_flow_id_lock, 0);
2162
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002163 return Status::OK;
2164}
2165
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002166Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
2167
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002168 bcmolt_flow_cfg cfg;
2169 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002170
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002171 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002172 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002173 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002174 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002175 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002176 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002177 } else if(flow_type.compare(multicast) == 0) {
2178 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002179 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002180 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002181 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
2182 }
2183
Jason Huang09b73ea2020-01-08 17:52:05 +08002184 OPENOLT_LOG(INFO, openolt_log_id, "flow remove received for flow_id=%u, flow_type=%s\n",
2185 flow_id, flow_type.c_str());
2186
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002187 bcmos_fastlock_lock(&acl_packet_trap_handler_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002188 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
2189 int32_t gemport_id = -1;
2190 int32_t intf_id = -1;
2191 int16_t acl_id = -1;
2192 if (flow_to_acl_map.count(fl_id_fl_dir) > 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002193
2194 acl_id_intf_id ac_id_if_id = flow_to_acl_map[fl_id_fl_dir];
2195 acl_id = std::get<0>(ac_id_if_id);
2196 intf_id = std::get<1>(ac_id_if_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002197 // cleanup acl only if it is a valid acl. If not valid acl, it may be datapath flow.
2198 if (acl_id >= 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002199 Status resp = handle_acl_rule_cleanup(acl_id, intf_id, flow_type);
Jason Huang09b73ea2020-01-08 17:52:05 +08002200 if (resp.ok()) {
2201 OPENOLT_LOG(INFO, openolt_log_id, "acl removed ok for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2202 flow_to_acl_map.erase(fl_id_fl_dir);
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002203
2204 // When flow is being removed, extract the value corresponding to flow_id from trap_to_host_pkt_info_with_vlan_for_flow_id if it exists
2205 if (trap_to_host_pkt_info_with_vlan_for_flow_id.count(flow_id) > 0) {
2206 trap_to_host_pkt_info_with_vlan pkt_info_with_vlan = trap_to_host_pkt_info_with_vlan_for_flow_id[flow_id];
2207 // Formulate the trap_to_host_pkt_info tuple key
2208 trap_to_host_pkt_info pkt_info(std::get<0>(pkt_info_with_vlan),
2209 std::get<1>(pkt_info_with_vlan),
2210 std::get<2>(pkt_info_with_vlan),
2211 std::get<3>(pkt_info_with_vlan));
2212 // Extract the value corresponding to trap_to_host_pkt_info key from trap_to_host_vlan_ids_for_trap_to_host_pkt_info
2213 // The value is a list of vlan_ids for the given trap_to_host_pkt_info key
2214 // Remove the vlan_id from the list that corresponded to the flow being removed.
2215 if (trap_to_host_vlan_ids_for_trap_to_host_pkt_info.count(pkt_info) > 0) {
2216 trap_to_host_vlan_ids_for_trap_to_host_pkt_info[pkt_info].remove(std::get<4>(pkt_info_with_vlan));
2217 } else {
2218 OPENOLT_LOG(ERROR, openolt_log_id, "trap-to-host with intf_type = %d, intf_id = %d, pkt_type = %d gemport_id = %d not found in trap_to_host_vlan_ids_for_trap_to_host_pkt_info map",
2219 std::get<0>(pkt_info_with_vlan), std::get<1>(pkt_info_with_vlan), std::get<2>(pkt_info_with_vlan), std::get<3>(pkt_info_with_vlan));
2220 }
2221
2222 } else {
2223 OPENOLT_LOG(ERROR, openolt_log_id, "flow id = %u not found in trap_to_host_pkt_info_with_vlan_for_flow_id map", flow_id);
2224 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002225 } else {
2226 OPENOLT_LOG(ERROR, openolt_log_id, "acl remove error for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2227 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002228 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002229 return resp;
2230 }
2231 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002232 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002233
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002234 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002235 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002236 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002237 flowid_to_gemport.erase(key.flow_id);
2238 port_to_flows[port_no].erase(key.flow_id);
2239 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
2240 }
2241 else
2242 {
2243 flowid_to_port.erase(key.flow_id);
2244 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002245 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002246
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002247 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002248
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002249 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002250 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002251 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 -04002252 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
2253 }
2254
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002255 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002256 if (flow_id_counters != 0) {
2257 std::map<flow_pair, int>::iterator it;
2258 for(it = flow_map.begin(); it != flow_map.end(); it++) {
2259 if (it->first.first == flow_id && it->first.second == key.flow_type) {
2260 flow_id_counters -= 1;
2261 flow_map.erase(it);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002262 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002263 }
2264 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002265 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
2266
Jason Huang09b73ea2020-01-08 17:52:05 +08002267 flow_to_acl_map.erase(fl_id_fl_dir);
2268
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002269 bcmos_fastlock_unlock(&data_lock, 0);
2270
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002271 return Status::OK;
2272}
2273
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002274bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
2275 bcmos_errno err;
2276 bcmolt_tm_sched_cfg tm_sched_cfg;
2277 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2278 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
2279
Jason Huangbf45ffb2019-10-30 17:29:02 +08002280 //check TM scheduler has configured or not
2281 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2282 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002283 #ifdef TEST_MODE
2284 // It is impossible to mock the setting of tm_sched_cfg.data.state because
2285 // the actual bcmolt_cfg_get passes the address of tm_sched_cfg.hdr and we cannot
2286 // set the tm_sched_cfg.data.state. So a new stub function is created and address
2287 // of tm_sched_cfg is passed. This is one-of case where we need to add test specific
2288 // code in production code.
2289 err = bcmolt_cfg_get__tm_sched_stub(dev_id, &tm_sched_cfg);
2290 #else
Jason Huangbf45ffb2019-10-30 17:29:02 +08002291 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002292 #endif
Jason Huangbf45ffb2019-10-30 17:29:02 +08002293 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002294 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 +08002295 return err;
2296 }
2297 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
2298 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
2299 return BCM_ERR_OK;
2300 }
2301
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002302 // bcmbal_tm_sched_owner
2303 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2304
2305 /**< The output of the tm_sched object instance */
2306 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
2307
2308 if (direction.compare(upstream) == 0) {
2309 // In upstream it is NNI scheduler
2310 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
2311 } else if (direction.compare(downstream) == 0) {
2312 // In downstream it is PON scheduler
2313 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2314 }
2315
2316 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2317
2318 // bcmbal_tm_sched_type
2319 // set the deafult policy to strict priority
2320 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2321
2322 // num_priorities: Max number of strict priority scheduling elements
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002323 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, NUM_OF_PRIORITIES);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002324
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002325 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2326 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002327 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
2328 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002329 return err;
2330 }
2331
2332 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2333 direction.c_str(), tm_sched_key.id, intf_id);
2334 return BCM_ERR_OK;
2335}
2336
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002337bcmos_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 -07002338 uint32_t alloc_id, ::tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
2339 ::tech_profile::SchedulingPolicy sched_policy, ::tech_profile::TrafficShapingInfo tf_sh_info,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002340 uint32_t tech_profile_id) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002341
2342 bcmos_errno err;
2343
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002344 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002345 bcmolt_tm_sched_cfg tm_sched_cfg;
2346 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002347 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 -04002348
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002349 // bcmbal_tm_sched_owner
2350 // In downstream it is sub_term scheduler
2351 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002352
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002353 /**< The output of the tm_sched object instance */
2354 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002355
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002356 // bcmbal_tm_sched_parent
2357 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2358 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
2359 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 +00002360 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002361 be achieved using the' virtual' type of attachment.
2362 tm_sched_owner.u.sub_term.intf_id = intf_id;
2363 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2364 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002365
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002366 // bcmbal_tm_sched_type
2367 // set the deafult policy to strict priority
2368 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002369
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002370 // num_priorities: Max number of strict priority scheduling elements
2371 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002372
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002373 // bcmbal_tm_shaping
2374 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2375 uint32_t cir = tf_sh_info.cir();
2376 uint32_t pir = tf_sh_info.pir();
2377 uint32_t burst = tf_sh_info.pbs();
2378 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2379 cir, pir, burst);
2380 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2381 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2382 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2383 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2384 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2385 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002386 }
2387
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002388 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002389 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002390 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002391intf_id %d, onu_id %d, uni_id %d, port_no %u, err = %s\n", tm_sched_key.id, intf_id, onu_id, uni_id, \
2392port_no, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002393 return err;
2394 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002395 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2396uni_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 -08002397
2398 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002399 bcmolt_itupon_alloc_cfg cfg;
2400 bcmolt_itupon_alloc_key key = { };
2401 key.pon_ni = intf_id;
2402 key.alloc_id = alloc_id;
2403 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
Burak Gurdag623fada2021-04-20 22:02:36 +00002404 /*
2405 PIR: Maximum Bandwidth
2406 CIR: Assured Bandwidth
2407 GIR: Fixed Bandwidth
2408 */
Burak Gurdag03919c72020-02-04 22:46:57 +00002409 int pir_bw = tf_sh_info.pir()*125; // conversion from kbps to bytes/sec
2410 int cir_bw = tf_sh_info.cir()*125; // conversion from kbps to bytes/sec
Burak Gurdag623fada2021-04-20 22:02:36 +00002411 int gir_bw = tf_sh_info.gir()*125; // conversion from kbps to bytes/sec
2412 int guaranteed_bw = cir_bw+gir_bw;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002413 //offset to match bandwidth granularity
2414 int offset_pir_bw = pir_bw%bw_granularity;
Burak Gurdag623fada2021-04-20 22:02:36 +00002415 int offset_gir_bw = gir_bw%bw_granularity;
2416 int offset_guaranteed_bw = guaranteed_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002417
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002418 pir_bw = pir_bw - offset_pir_bw;
Burak Gurdag623fada2021-04-20 22:02:36 +00002419 gir_bw = gir_bw - offset_gir_bw;
2420 guaranteed_bw = guaranteed_bw - offset_guaranteed_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002421
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002422 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002423
Burak Gurdag623fada2021-04-20 22:02:36 +00002424 OPENOLT_LOG(INFO, openolt_log_id, "Creating alloc_id %d with pir = %d bytes/sec, cir = %d bytes/sec, gir = %d bytes/sec, additional_bw = %d.\n", alloc_id, pir_bw, cir_bw, gir_bw, additional_bw);
2425
2426 if (pir_bw == 0) {
2427 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be at least %d bytes/sec\n",
2428 (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2429 return BCM_ERR_PARM;
2430 } else if (pir_bw < guaranteed_bw) {
2431 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed bandwidth (%d)\n",
2432 pir_bw, guaranteed_bw);
2433 return BCM_ERR_PARM;
2434 }
2435
2436 // Setting additional bw eligibility and validating bw provisionings
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002437 switch (additional_bw) {
Burak Gurdag623fada2021-04-20 22:02:36 +00002438
2439 case tech_profile::AdditionalBW::AdditionalBW_BestEffort: //AdditionalBW_BestEffort - For T-Cont types 4 & 5
2440 if (pir_bw == guaranteed_bw) {
2441 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2442bandwidth for additional bandwidth eligibility of type Best Effort\n");
2443 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002444 }
2445 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2446 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002447
2448 case tech_profile::AdditionalBW::AdditionalBW_NA: //AdditionalBW_NA - For T-Cont types 3 & 5
2449 if (guaranteed_bw == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002450 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2451additional bandwidth eligibility of type Non-Assured (NA)\n");
2452 return BCM_ERR_PARM;
Burak Gurdag623fada2021-04-20 22:02:36 +00002453 } else if (pir_bw == guaranteed_bw) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002454 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
Burak Gurdag623fada2021-04-20 22:02:36 +00002455bandwidth for additional bandwidth eligibility of type Non-Assured\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002456 return BCM_ERR_PARM;
2457 }
2458 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2459 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002460
2461 case tech_profile::AdditionalBW::AdditionalBW_None: //AdditionalBW_None - For T-Cont types 1 & 2
2462 if (guaranteed_bw != pir_bw) {
2463 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be equal to maximum bandwidth \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002464for additional bandwidth eligibility of type None\n");
2465 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002466 }
2467 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2468 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002469
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002470 default:
Burak Gurdag623fada2021-04-20 22:02:36 +00002471 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid additional bandwidth eligibility value (%d) supplied.\n", additional_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002472 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002473 }
Burak Gurdag623fada2021-04-20 22:02:36 +00002474
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002475 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2476 in a fine granularity. */
2477 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
Burak Gurdag623fada2021-04-20 22:02:36 +00002478 /* Since we can assign minimum 64000 bytes/sec for cbr_rt_bw, we prefer assigning
2479 gir_bw to cbr_nrt_bw to allow smaller amounts.
2480 TODO: Specify CBR_RT_BW and CBR_NRT_BW separately from VOLTHA */
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002481 /* Fixed Bandwidth with no critical requirement of shaping */
Burak Gurdag623fada2021-04-20 22:02:36 +00002482 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, gir_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002483 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
Burak Gurdag623fada2021-04-20 22:02:36 +00002484 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, guaranteed_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002485 /* Maximum allocated bandwidth allowed for this alloc ID */
2486 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
Burak Gurdag623fada2021-04-20 22:02:36 +00002487
2488 if (pir_bw == gir_bw) { // T-Cont Type 1 --> set alloc type to NONE
2489 // the condition cir_bw == 0 is implicitly satistied
2490 OPENOLT_LOG(INFO, openolt_log_id, "Setting alloc type to NONE since maximum bandwidth is equal to fixed bandwidth\n");
2491 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NONE);
2492 } else { // For other T-Cont types, set alloc type to NSR. TODO: read the default from a config file.
2493 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
2494 }
2495
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002496 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002497 for skipped allocations during quiet window */
2498 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2499 /**< Allocation Profile index for CBR non-RT Bandwidth */
2500 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2501 /**< Allocation Profile index for CBR RT Bandwidth */
2502 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2503 /**< Alloc ID Weight used in case of Extended DBA mode */
2504 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2505 /**< Alloc ID Priority used in case of Extended DBA mode */
2506 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2507 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002508
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002509 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002510 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002511 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
Burak Gurdag623fada2021-04-20 22:02:36 +00002512port_no %u, alloc_id %d, err = %s (%s)\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err), cfg.hdr.hdr.err_text);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002513 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002514 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002515#ifndef SCALE_AND_PERF
Girish Gowdra96461052019-11-22 20:13:59 +05302516 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
2517 if (err) {
2518 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2519port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
2520 return err;
2521 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002522#endif
Girish Gowdra96461052019-11-22 20:13:59 +05302523
2524 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
2525port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
2526
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002527 }
2528
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002529 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002530}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002531
Girish Gowdra252f4972020-09-07 21:24:01 -07002532Status CreateTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002533 uint32_t intf_id = traffic_scheds->intf_id();
2534 uint32_t onu_id = traffic_scheds->onu_id();
2535 uint32_t uni_id = traffic_scheds->uni_id();
2536 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002537 std::string direction;
2538 unsigned int alloc_id;
Girish Gowdra252f4972020-09-07 21:24:01 -07002539 ::tech_profile::SchedulerConfig sched_config;
2540 ::tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002541 uint32_t priority;
2542 uint32_t weight;
Girish Gowdra252f4972020-09-07 21:24:01 -07002543 ::tech_profile::SchedulingPolicy sched_policy;
2544 ::tech_profile::TrafficShapingInfo traffic_shaping_info;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002545 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002546 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002547
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002548 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002549 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002550
2551 direction = GetDirection(traffic_sched.direction());
2552 if (direction.compare("direction-not-supported") == 0)
2553 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2554
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002555 alloc_id = traffic_sched.alloc_id();
2556 sched_config = traffic_sched.scheduler();
2557 additional_bw = sched_config.additional_bw();
2558 priority = sched_config.priority();
2559 weight = sched_config.weight();
2560 sched_policy = sched_config.sched_policy();
2561 traffic_shaping_info = traffic_sched.traffic_shaping_info();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002562 tech_profile_id = traffic_sched.tech_profile_id();
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002563 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002564 sched_policy, traffic_shaping_info, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002565 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002566 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002567 return bcm_to_grpc_err(err, "Failed to create scheduler");
2568 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002569 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002570 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002571}
Jonathan Davis70c21812018-07-19 15:32:10 -04002572
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002573bcmos_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 -04002574
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002575 bcmos_errno err;
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302576 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302577 bcmolt_status los_status;
Girish Gowdra96461052019-11-22 20:13:59 +05302578 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002579
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002580 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002581 bcmolt_itupon_alloc_cfg cfg;
2582 bcmolt_itupon_alloc_key key = { };
2583 key.pon_ni = intf_id;
2584 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302585 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002586
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002587 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002588 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2589 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002590 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2591 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002592 return err;
2593 }
Girish Gowdra96461052019-11-22 20:13:59 +05302594
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302595 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302596 if (err == BCM_ERR_OK) {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302597 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_OFF) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002598#ifndef SCALE_AND_PERF
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302599 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 +05302600 intf_id);
2601 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2602 if (err) {
2603 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2604 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
2605 return err;
2606 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002607#endif
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302608 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302609 else if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_ON) {
2610 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is enabled but LoS status is ON, not waiting for alloc cfg clear response\n",
2611 intf_id);
2612 }
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302613 else if (state == BCMOLT_INTERFACE_STATE_INACTIVE) {
2614 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is disabled, not waiting for alloc cfg clear response\n",
2615 intf_id);
2616 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302617 } else {
2618 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 +05302619 intf_id, bcmos_strerror(err));
Girish Gowdra96461052019-11-22 20:13:59 +05302620 return err;
2621 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002622 } else if (direction == downstream) {
2623 bcmolt_tm_sched_cfg cfg;
2624 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002625
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002626 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2627 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302628 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002629 } else {
2630 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2631 return BCM_ERR_OK;
2632 }
Girish Gowdra96461052019-11-22 20:13:59 +05302633
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002634 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2635 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2636 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002637 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002638intf_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 +00002639 return err;
2640 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002641 }
2642
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002643 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d, tech_profile_id %d\n",
2644 direction.c_str(), sched_id, intf_id, onu_id, tech_profile_id);
2645 free_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002646 return BCM_ERR_OK;
2647}
2648
Girish Gowdra252f4972020-09-07 21:24:01 -07002649Status RemoveTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002650 uint32_t intf_id = traffic_scheds->intf_id();
2651 uint32_t onu_id = traffic_scheds->onu_id();
2652 uint32_t uni_id = traffic_scheds->uni_id();
2653 std::string direction;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002654 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002655 bcmos_errno err;
2656
2657 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002658 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002659
2660 direction = GetDirection(traffic_sched.direction());
2661 if (direction.compare("direction-not-supported") == 0)
2662 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2663
2664 int alloc_id = traffic_sched.alloc_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002665 int tech_profile_id = traffic_sched.tech_profile_id();
2666 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002667 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002668 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002669 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2670 }
2671 }
2672 return Status::OK;
2673}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002674
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002675bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2676 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002677 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002678 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2679 bcmolt_tm_qmp_key tm_qmp_key;
2680 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002681
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002682 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2683 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002684 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed tm queue mapping profile count is 16.\n");
2685 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002686 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002687
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002688 tm_qmp_key.id = tm_qmp_id;
2689 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2690 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2691 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002692
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002693 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2694 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2695 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002696 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2697 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002698
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002699 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002700 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002701 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2702 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002703 return err;
2704 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002705
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002706 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2707 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002708 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002709}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002710
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002711bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2712 bcmos_errno err;
2713 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2714 bcmolt_tm_qmp_key tm_qmp_key;
2715 tm_qmp_key.id = tm_qmp_id;
2716
2717 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2718 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2719 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002720 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2721 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002722 return err;
2723 }
2724
2725 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2726 tm_qmp_key.id);
2727 return BCM_ERR_OK;
2728}
2729
2730bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2731 bcmos_errno err;
2732
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002733 /* Create default queues on the given PON/NNI scheduler */
2734 for (int queue_id = 0; queue_id < NUMBER_OF_DEFAULT_INTERFACE_QUEUES; queue_id++) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002735 bcmolt_tm_queue_cfg tm_queue_cfg;
2736 bcmolt_tm_queue_key tm_queue_key = {};
2737 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2738 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002739 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2740 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2741 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002742
2743 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2744 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2745 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2746
2747 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2748 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002749 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", \
2750 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 +00002751 return err;
2752 }
2753
2754 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2755 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2756 }
2757 return BCM_ERR_OK;
2758}
2759
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002760bcmos_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 +00002761 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 +00002762 bcmos_errno err;
2763 bcmolt_tm_queue_cfg cfg;
2764 bcmolt_tm_queue_key key = { };
2765 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 +00002766gemport_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 +00002767
2768 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002769 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002770
2771 if (priority > 7) {
2772 return BCM_ERR_RANGE;
2773 }
2774
2775 /* FIXME: The upstream queues have to be created once only.
2776 The upstream queues on the NNI scheduler are shared by all subscribers.
2777 When the first scheduler comes in, the queues get created, and are re-used by all others.
2778 Also, these queues should be present until the last subscriber exits the system.
2779 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2780
2781 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2782 for each GEM in TECH PROFILE */
2783 key.id = queue_id_list[priority];
2784
2785 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2786 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2787 key.id = 0;
2788 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2789 }
2790 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2791 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2792 }
2793 else {
2794 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2795 }
2796
2797 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2798
2799 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2800 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
2801
2802 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2803 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002804 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002805sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, tech_profile_id %d, err = %s\n", \
2806 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 +00002807 return err;
2808 }
2809
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302810 if (direction == upstream || direction == downstream) {
Thiyagarajan Subramani19168f52021-05-25 23:26:41 +05302811 Status st = install_gem_port(access_intf_id, onu_id, uni_id, gemport_id, board_technology);
Girish Gowdra252f4972020-09-07 21:24:01 -07002812 if (st.error_code() != grpc::StatusCode::ALREADY_EXISTS && st.error_code() != grpc::StatusCode::OK) {
2813 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);
2814 return BCM_ERR_INTERNAL;
2815 }
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002816 if (direction == upstream) {
2817 // Create the pon-gem to onu-uni mapping
2818 pon_gem pg(access_intf_id, gemport_id);
2819 onu_uni ou(onu_id, uni_id);
2820 bcmos_fastlock_lock(&pon_gem_to_onu_uni_map_lock);
2821 pon_gem_to_onu_uni_map[pg] = ou;
2822 bcmos_fastlock_unlock(&pon_gem_to_onu_uni_map_lock, 0);
2823 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002824 }
2825
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002826 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 +00002827intf_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 +00002828 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002829}
2830
Girish Gowdra252f4972020-09-07 21:24:01 -07002831Status CreateTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002832 uint32_t intf_id = traffic_queues->intf_id();
2833 uint32_t onu_id = traffic_queues->onu_id();
2834 uint32_t uni_id = traffic_queues->uni_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002835 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002836 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002837 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002838 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002839 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 +00002840
2841 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2842 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2843 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2844 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002845 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002846
2847 direction = GetDirection(traffic_queue.direction());
2848 if (direction.compare("direction-not-supported") == 0)
2849 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2850
2851 queues_priority_q[i] = traffic_queue.priority();
2852 queues_pbit_map[i] = traffic_queue.pbit_map();
2853 }
2854
2855 std::vector<uint32_t> tmq_map_profile(8, 0);
2856 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2857 queues_priority_q, COUNT_OF(queues_priority_q));
2858 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002859 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002860
2861 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2862 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002863 err = CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2864 if (err != BCM_ERR_OK) {
2865 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2866 return bcm_to_grpc_err(err, "Failed to create tm queue mapping profile");
2867 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002868 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2869 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2870 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2871 }
2872 }
2873
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002874 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002875 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002876
2877 direction = GetDirection(traffic_queue.direction());
2878 if (direction.compare("direction-not-supported") == 0)
2879 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2880
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002881 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 +00002882
Girish Gowdruf26cf882019-05-01 23:47:58 -07002883 // If the queue exists already, lets not return failure and break the loop.
2884 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002885 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002886 return bcm_to_grpc_err(err, "Failed to create queue");
2887 }
2888 }
2889 return Status::OK;
2890}
2891
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002892bcmos_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 +00002893 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 +00002894 bcmolt_tm_queue_cfg cfg;
2895 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002896 bcmos_errno err;
2897
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302898 // Gemports are bi-directional (except in multicast case). We create the gem port when we create the
2899 // upstream/downstream queue (see CreateQueue function) and it makes sense to delete them when remove the queues.
2900 // For multicast case we do not manage the install/remove of gem port in agent application. It is managed by BAL.
2901 if (direction == upstream || direction == downstream) {
Thiyagarajan Subramani19168f52021-05-25 23:26:41 +05302902 Status st = remove_gem_port(access_intf_id, onu_id, uni_id, gemport_id, board_technology);
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302903 if (st.error_code() != grpc::StatusCode::OK) {
2904 OPENOLT_LOG(ERROR, openolt_log_id, "failed to remove gemport=%d, access_intf=%d, onu_id=%d\n", gemport_id, access_intf_id, onu_id);
2905 return BCM_ERR_INTERNAL;
2906 }
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002907 if (direction == upstream) {
2908 // Remove the pon-gem to onu-uni mapping
2909 pon_gem pg(access_intf_id, gemport_id);
2910 bcmos_fastlock_lock(&pon_gem_to_onu_uni_map_lock);
2911 pon_gem_to_onu_uni_map.erase(pg);
2912 bcmos_fastlock_unlock(&pon_gem_to_onu_uni_map_lock, 0);
2913 }
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302914 }
2915
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002916 if (direction == downstream) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002917 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2918 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 +00002919 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002920 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002921 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 -08002922 return BCM_ERR_OK;
2923 }
2924 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002925 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2926 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002927 return BCM_ERR_OK;
2928 }
2929
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002930 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2931 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2932 // Reset the queue id to 0 when using fixed queue.
2933 key.id = 0;
2934 }
2935 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2936 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2937 }
2938 else {
2939 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2940 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002941
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002942 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2943 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002944 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002945 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, queue_id %d, sched_id %d, \
2946tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n",
2947 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 -08002948 return err;
2949 }
2950
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002951 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2952intf_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 -08002953
2954 return BCM_ERR_OK;
2955}
2956
Girish Gowdra252f4972020-09-07 21:24:01 -07002957Status RemoveTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002958 uint32_t intf_id = traffic_queues->intf_id();
2959 uint32_t onu_id = traffic_queues->onu_id();
2960 uint32_t uni_id = traffic_queues->uni_id();
2961 uint32_t port_no = traffic_queues->port_no();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002962 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002963 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002964 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002965 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002966 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 +00002967
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002968 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002969 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002970
2971 direction = GetDirection(traffic_queue.direction());
2972 if (direction.compare("direction-not-supported") == 0)
2973 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2974
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002975 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 -08002976 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002977 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002978 return bcm_to_grpc_err(err, "Failed to remove queue");
2979 }
Jonathan Davis70c21812018-07-19 15:32:10 -04002980 }
2981
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002982 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 +00002983 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002984 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002985
2986 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
2987 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002988 err = RemoveTrafficQueueMappingProfile(tm_qmp_id);
2989 if (err != BCM_ERR_OK) {
2990 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2991 return bcm_to_grpc_err(err, "Failed to remove tm queue mapping profile");
2992 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002993 }
2994 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002995 clear_qos_type(intf_id, onu_id, uni_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04002996 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04002997}
Jason Huangbf45ffb2019-10-30 17:29:02 +08002998
Girish Gowdra252f4972020-09-07 21:24:01 -07002999Status PerformGroupOperation_(const ::openolt::Group *group_cfg) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003000
3001 bcmos_errno err;
3002 bcmolt_group_key key = {};
3003 bcmolt_group_cfg grp_cfg_obj;
3004 bcmolt_group_members_update grp_mem_upd;
3005 bcmolt_members_update_command grp_mem_upd_cmd;
3006 bcmolt_group_member_info member_info = {};
3007 bcmolt_group_member_info_list_u8 members = {};
3008 bcmolt_intf_ref interface_ref = {};
3009 bcmolt_egress_qos egress_qos = {};
3010 bcmolt_tm_sched_ref tm_sched_ref = {};
3011 bcmolt_action a_val = {};
3012
3013 uint32_t group_id = group_cfg->group_id();
3014
3015 OPENOLT_LOG(INFO, openolt_log_id, "PerformGroupOperation request received for Group %d\n", group_id);
3016
3017 if (group_id >= 0) {
3018 key.id = group_id;
3019 }
3020 else {
3021 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
3022 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
3023 }
3024
3025 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3026 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
3027
3028 OPENOLT_LOG(INFO, openolt_log_id, "Checking if Group %d exists...\n",group_id);
3029
3030 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
3031 if (err != BCM_ERR_OK) {
3032 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
3033 return bcm_to_grpc_err(err, "Error in querying group");
3034 }
3035
3036 members.len = group_cfg->members_size();
3037
3038 // IMPORTANT: A member cannot be added to a group if the group type is not determined.
3039 // Group type is determined after a flow is assigned to it.
3040 // Therefore, a group must be created first, then a flow (with multicast type) must be assigned to it.
3041 // Only then we can add members to the group.
3042
3043 // if group does not exist, create it and return.
3044 if (grp_cfg_obj.data.state == BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
3045
3046 if (members.len != 0) {
3047 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);
3048 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Non-empty member list given for non-existent group");
3049 } else {
3050
3051 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3052 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, cookie, key.id);
3053
3054 /* Setting group actions and action parameters, if any.
3055 Only remove_outer_tag and translate_inner_tag actions and i_vid action parameter
3056 are supported for multicast groups in BAL 3.1.
3057 */
3058 const ::openolt::Action& action = group_cfg->action();
3059 const ::openolt::ActionCmd &cmd = action.cmd();
3060
3061 bcmolt_action_cmd_id cmd_bmask = BCMOLT_ACTION_CMD_ID_NONE;
3062 if (cmd.remove_outer_tag()) {
3063 OPENOLT_LOG(INFO, openolt_log_id, "Action remove_outer_tag applied to Group %d.\n", group_id);
3064 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
3065 }
3066
3067 if (cmd.translate_inner_tag()) {
3068 OPENOLT_LOG(INFO, openolt_log_id, "Action translate_inner_tag applied to Group %d.\n", group_id);
3069 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG);
3070 }
3071
3072 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, cmd_bmask);
3073
3074 if (action.i_vid()) {
3075 OPENOLT_LOG(INFO, openolt_log_id, "Setting action parameter i_vid=%d for Group %d.\n", action.i_vid(), group_id);
3076 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
3077 }
3078
3079 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, action, a_val);
3080
3081 // Create group
3082 err = bcmolt_cfg_set(dev_id, &(grp_cfg_obj.hdr));
3083
3084 if (BCM_ERR_OK != err) {
3085 BCM_LOG(ERROR, openolt_log_id, "Failed to create Group %d, err = %s (%d)\n", key.id, bcmos_strerror(err), err);
3086 return bcm_to_grpc_err(err, "Error in creating group");
3087 }
3088
3089 BCM_LOG(INFO, openolt_log_id, "Group %d has been created and configured with empty member list.\n", key.id);
3090 return Status::OK;
3091 }
3092 }
3093
3094 // The group already exists. Continue configuring it according to the update member command.
3095
3096 OPENOLT_LOG(INFO, openolt_log_id, "Configuring existing Group %d.\n",group_id);
3097
3098 // MEMBER LIST CONSTRUCTION
3099 // Note that members.len can be 0 here. if the group already exists and the command is SET then sending
3100 // empty list to the group is a legit operation and this actually empties the member list.
3101 members.arr = (bcmolt_group_member_info*)bcmos_calloc((members.len)*sizeof(bcmolt_group_member_info));
3102
3103 if (!members.arr) {
3104 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to allocate memory for group member list.\n");
3105 return grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "Memory exhausted during member list creation");
3106 }
3107
3108 /* SET GROUP MEMBERS UPDATE COMMAND */
Girish Gowdra252f4972020-09-07 21:24:01 -07003109 ::openolt::Group::GroupMembersCommand command = group_cfg->command();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003110 switch(command) {
Girish Gowdra252f4972020-09-07 21:24:01 -07003111 case ::openolt::Group::SET_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003112 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_SET;
3113 OPENOLT_LOG(INFO, openolt_log_id, "Setting %d members for Group %d.\n", members.len, group_id);
3114 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003115 case ::openolt::Group::ADD_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003116 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_ADD;
3117 OPENOLT_LOG(INFO, openolt_log_id, "Adding %d members to Group %d.\n", members.len, group_id);
3118 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003119 case ::openolt::Group::REMOVE_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003120 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_REMOVE;
3121 OPENOLT_LOG(INFO, openolt_log_id, "Removing %d members from Group %d.\n", members.len, group_id);
3122 break;
3123 default :
3124 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid value %d for group member command.\n", command);
3125 bcmos_free(members.arr);
3126 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group member command");
3127 }
3128
3129 // SET MEMBERS LIST
3130 for (int i = 0; i < members.len; i++) {
3131
Girish Gowdra252f4972020-09-07 21:24:01 -07003132 if (command == ::openolt::Group::REMOVE_MEMBERS) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003133 OPENOLT_LOG(INFO, openolt_log_id, "Removing group member %d from group %d\n",i,key.id);
3134 } else {
3135 OPENOLT_LOG(INFO, openolt_log_id, "Adding group member %d to group %d\n",i,key.id);
3136 }
3137
Girish Gowdra252f4972020-09-07 21:24:01 -07003138 ::openolt::GroupMember *member = (::openolt::GroupMember *) &group_cfg->members()[i];
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003139
3140 // Set member interface type
Girish Gowdra252f4972020-09-07 21:24:01 -07003141 ::openolt::GroupMember::InterfaceType if_type = member->interface_type();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003142 switch(if_type){
Girish Gowdra252f4972020-09-07 21:24:01 -07003143 case ::openolt::GroupMember::PON :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003144 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_PON);
3145 OPENOLT_LOG(INFO, openolt_log_id, "Interface type PON is assigned to GroupMember %d\n",i);
3146 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003147 case ::openolt::GroupMember::EPON_1G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003148 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_1_G);
3149 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_1G is assigned to GroupMember %d\n",i);
3150 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003151 case ::openolt::GroupMember::EPON_10G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003152 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_10_G);
3153 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_10G is assigned to GroupMember %d\n",i);
3154 break;
3155 default :
3156 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid interface type value %d for GroupMember %d.\n",if_type,i);
3157 bcmos_free(members.arr);
3158 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface type for a group member");
3159 }
3160
3161 // Set member interface id
3162 if (member->interface_id() >= 0) {
3163 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_id, member->interface_id());
3164 OPENOLT_LOG(INFO, openolt_log_id, "Interface %d is assigned to GroupMember %d\n", member->interface_id(), i);
3165 } else {
3166 bcmos_free(members.arr);
3167 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface id for a group member");
3168 }
3169
3170 // Set member interface_ref
3171 BCMOLT_FIELD_SET(&member_info, group_member_info, intf, interface_ref);
3172
3173 // Set member gem_port_id. This must be a multicast gemport.
3174 if (member->gem_port_id() >= 0) {
3175 BCMOLT_FIELD_SET(&member_info, group_member_info, svc_port_id, member->gem_port_id());
3176 OPENOLT_LOG(INFO, openolt_log_id, "GEM Port %d is assigned to GroupMember %d\n", member->gem_port_id(), i);
3177 } else {
3178 bcmos_free(members.arr);
3179 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid gem port id for a group member");
3180 }
3181
3182 // Set member scheduler id and queue_id
3183 uint32_t tm_sched_id = get_default_tm_sched_id(member->interface_id(), downstream);
3184 OPENOLT_LOG(INFO, openolt_log_id, "Scheduler %d is assigned to GroupMember %d\n", tm_sched_id, i);
3185 BCMOLT_FIELD_SET(&tm_sched_ref, tm_sched_ref, id, tm_sched_id);
3186 BCMOLT_FIELD_SET(&egress_qos, egress_qos, tm_sched, tm_sched_ref);
3187
3188 // We assume that all multicast traffic destined to a PON port is using the same fixed queue.
3189 uint32_t tm_queue_id;
3190 if (member->priority() >= 0 && member->priority() < NUMBER_OF_DEFAULT_INTERFACE_QUEUES) {
3191 tm_queue_id = queue_id_list[member->priority()];
3192 OPENOLT_LOG(INFO, openolt_log_id, "Queue %d is assigned to GroupMember %d\n", tm_queue_id, i);
3193 BCMOLT_FIELD_SET(&egress_qos, egress_qos, type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
3194 BCMOLT_FIELD_SET(&egress_qos.u.fixed_queue, egress_qos_fixed_queue, queue_id, tm_queue_id);
3195 } else {
3196 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid fixed queue priority/ID %d for GroupMember %d\n", member->priority(), i);
3197 bcmos_free(members.arr);
3198 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid queue priority for a group member");
3199 }
3200
3201 BCMOLT_FIELD_SET(&member_info, group_member_info, egress_qos, egress_qos);
3202 BCMOLT_ARRAY_ELEM_SET(&(members), i, member_info);
3203 }
3204
3205 BCMOLT_OPER_INIT(&grp_mem_upd, group, members_update, key);
3206 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.members, members);
3207 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.command, grp_mem_upd_cmd);
3208
3209 err = bcmolt_oper_submit(dev_id, &(grp_mem_upd.hdr));
3210 bcmos_free(members.arr);
3211
3212 if (BCM_ERR_OK != err) {
3213 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);
3214 return bcm_to_grpc_err(err, "Failed to submit members update operation for the group");
3215 }
3216
3217 OPENOLT_LOG(INFO, openolt_log_id, "Successfully submitted members update operation for Group %d\n", key.id);
3218
3219 return Status::OK;
3220}
Burak Gurdageb4ca2e2020-06-15 07:48:26 +00003221
3222Status DeleteGroup_(uint32_t group_id) {
3223
3224 bcmos_errno err = BCM_ERR_OK;
3225 bcmolt_group_cfg grp_cfg_obj;
3226 bcmolt_group_key key = {};
3227
3228
3229 OPENOLT_LOG(INFO, openolt_log_id, "Delete request received for group %d\n", group_id);
3230
3231 if (group_id >= 0) {
3232 key.id = group_id;
3233 } else {
3234 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
3235 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
3236 }
3237
3238 /* init the BAL INIT API */
3239 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3240
3241 OPENOLT_LOG(DEBUG, openolt_log_id, "Checking if group %d exists...\n",group_id);
3242
3243 // CONFIGURE GROUP MEMBERS
3244 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
3245 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
3246
3247 if (err != BCM_ERR_OK) {
3248 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
3249 return bcm_to_grpc_err(err, "Error in querying group");
3250 }
3251
3252 if (grp_cfg_obj.data.state != BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
3253 OPENOLT_LOG(DEBUG, openolt_log_id, "Group %d exists. Will be deleted.\n",group_id);
3254 err = bcmolt_cfg_clear(dev_id, &(grp_cfg_obj.hdr));
3255 if (err != BCM_ERR_OK) {
3256 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d cannot be deleted err = %s (%d).\n", group_id, bcmos_strerror(err), err);
3257 return bcm_to_grpc_err(err, "Failed to delete group");;
3258 }
3259 } else {
3260 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d does not exist.\n", group_id);
3261 return Status(grpc::StatusCode::NOT_FOUND, "Group not found");
3262 }
3263
3264 OPENOLT_LOG(INFO, openolt_log_id, "Group %d has been deleted successfully.\n", group_id);
3265 return Status::OK;
Jason Huang1d9cfce2020-05-20 22:58:47 +08003266}
3267
Girish Gowdra252f4972020-09-07 21:24:01 -07003268Status GetLogicalOnuDistanceZero_(uint32_t intf_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003269 bcmos_errno err = BCM_ERR_OK;
3270 uint32_t mld = 0;
3271 double LD0;
3272
3273 err = getOnuMaxLogicalDistance(intf_id, &mld);
3274 if (err != BCM_ERR_OK) {
3275 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3276 }
3277
3278 LD0 = LOGICAL_DISTANCE(mld*1000, MINIMUM_ONU_RESPONSE_RANGING_TIME, ONU_BIT_TRANSMISSION_DELAY);
3279 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance zero is %f, (PON %d)\n", LD0, intf_id);
3280 response->set_intf_id(intf_id);
3281 response->set_logical_onu_distance_zero(LD0);
3282
3283 return Status::OK;
3284}
3285
Girish Gowdra252f4972020-09-07 21:24:01 -07003286Status GetLogicalOnuDistance_(uint32_t intf_id, uint32_t onu_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003287 bcmos_errno err = BCM_ERR_OK;
3288 bcmolt_itu_onu_params itu = {};
3289 bcmolt_onu_cfg onu_cfg;
3290 bcmolt_onu_key onu_key = {};
3291 uint32_t mld = 0;
3292 double LDi;
3293
3294 onu_key.pon_ni = intf_id;
3295 onu_key.onu_id = onu_id;
3296
3297 err = getOnuMaxLogicalDistance(intf_id, &mld);
3298 if (err != BCM_ERR_OK) {
3299 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3300 }
3301
3302 /* Initialize the API struct. */
3303 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
3304 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
3305 BCMOLT_FIELD_SET_PRESENT(&itu, itu_onu_params, ranging_time);
3306 BCMOLT_FIELD_SET(&onu_cfg.data, onu_cfg_data, itu, itu);
3307 #ifdef TEST_MODE
3308 // It is impossible to mock the setting of onu_cfg.data.onu_state because
3309 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
3310 // set the onu_cfg.data.onu_state. So a new stub function is created and address
3311 // of onu_cfg is passed. This is one-of case where we need to add test specific
3312 // code in production code.
3313 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
3314 #else
3315 /* Call API function. */
3316 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
3317 #endif
3318 if (err != BCM_ERR_OK) {
3319 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);
3320 return bcm_to_grpc_err(err, "Failed to retrieve ONU ranging time");
3321 }
3322
3323 if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_ACTIVE) {
3324 OPENOLT_LOG(ERROR, openolt_log_id, "ONU is not yet activated (PON %d, ONU id %d)\n", intf_id, onu_id);
3325 return bcm_to_grpc_err(BCM_ERR_PARM, "ONU is not yet activated\n");
3326 }
3327
3328 LDi = LOGICAL_DISTANCE(mld*1000, onu_cfg.data.itu.ranging_time, ONU_BIT_TRANSMISSION_DELAY);
3329 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance is %f, (PON %d, ONU id %d)\n", LDi, intf_id, onu_id);
3330 response->set_intf_id(intf_id);
3331 response->set_onu_id(onu_id);
3332 response->set_logical_onu_distance(LDi);
3333
3334 return Status::OK;
3335}
Burak Gurdag74e3ab82020-12-17 13:35:06 +00003336
3337Status GetOnuStatistics_(uint32_t intf_id, uint32_t onu_id, openolt::OnuStatistics* onu_stats) {
3338 bcmos_errno err;
3339
3340 err = get_onu_statistics((bcmolt_interface_id)intf_id, (bcmolt_onu_id)onu_id, onu_stats);
3341
3342 if (err != BCM_ERR_OK) {
3343 OPENOLT_LOG(ERROR, openolt_log_id, "retrieval of ONU statistics failed - PON ID = %u, ONU ID = %u, err = %d - %s", intf_id, onu_id, err, bcmos_strerror(err));
3344 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of ONU statistics failed");
3345 }
3346
3347 OPENOLT_LOG(INFO, openolt_log_id, "retrieved ONU statistics for PON ID = %d, ONU ID = %d\n", (int)intf_id, (int)onu_id);
3348 return Status::OK;
3349}
3350
3351Status GetGemPortStatistics_(uint32_t intf_id, uint32_t gemport_id, openolt::GemPortStatistics* gemport_stats) {
3352 bcmos_errno err;
3353
3354 err = get_gemport_statistics((bcmolt_interface_id)intf_id, (bcmolt_gem_port_id)gemport_id, gemport_stats);
3355
3356 if (err != BCM_ERR_OK) {
3357 OPENOLT_LOG(ERROR, openolt_log_id, "retrieval of GEMPORT statistics failed - PON ID = %u, ONU ID = %u, err = %d - %s", intf_id, gemport_id, err, bcmos_strerror(err));
3358 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of GEMPORT statistics failed");
3359 }
3360
3361 OPENOLT_LOG(INFO, openolt_log_id, "retrieved GEMPORT statistics for PON ID = %d, GEMPORT ID = %d\n", (int)intf_id, (int)gemport_id);
3362 return Status::OK;
3363}
Orhan Kupusogluec57af02021-05-12 12:38:17 +00003364
3365Status GetPonRxPower_(uint32_t intf_id, uint32_t onu_id, openolt::PonRxPowerData* response) {
3366 bcmos_errno err = BCM_ERR_OK;
3367
3368 // check the PON intf id
3369 if (intf_id >= MAX_SUPPORTED_PON) {
3370 err = BCM_ERR_PARM;
3371 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pon intf_id - intf_id: %d, onu_id: %d\n",
3372 intf_id, onu_id);
3373 return bcm_to_grpc_err(err, "invalid pon intf_id");
3374 }
3375
3376 bcmolt_onu_rssi_measurement onu_oper; /* declare main API struct */
3377 bcmolt_onu_key onu_key; /**< Object key. */
3378 onu_rssi_compltd_key key(intf_id, onu_id);
3379 Queue<onu_rssi_complete_result> queue;
3380
3381 OPENOLT_LOG(INFO, openolt_log_id, "GetPonRxPower - intf_id %d, onu_id %d\n", intf_id, onu_id);
3382
3383 onu_key.onu_id = onu_id;
3384 onu_key.pon_ni = intf_id;
3385 /* Initialize the API struct. */
3386 BCMOLT_OPER_INIT(&onu_oper, onu, rssi_measurement, onu_key);
3387 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
3388 if (err == BCM_ERR_OK) {
3389 // initialize map
3390 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3391 onu_rssi_compltd_map.insert({key, &queue});
3392 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3393 } else {
3394 OPENOLT_LOG(ERROR, openolt_log_id, "failed to measure rssi rx power - intf_id: %d, onu_id: %d, err = %s (%d): %s\n",
3395 intf_id, onu_id, bcmos_strerror(err), err, onu_oper.hdr.hdr.err_text);
3396 return bcm_to_grpc_err(err, "failed to measure rssi rx power");
3397 }
3398
3399 onu_rssi_complete_result completed{};
3400 if (!queue.pop(completed, ONU_RSSI_COMPLETE_WAIT_TIMEOUT)) {
3401 // invalidate the queue pointer
3402 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3403 onu_rssi_compltd_map[key] = NULL;
3404 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3405 err = BCM_ERR_TIMEOUT;
3406 OPENOLT_LOG(ERROR, openolt_log_id, "timeout waiting for RSSI Measurement Completed indication intf_id %d, onu_id %d\n",
3407 intf_id, onu_id);
3408 } else {
3409 OPENOLT_LOG(INFO, openolt_log_id, "RSSI Rx power - intf_id: %d, onu_id: %d, status: %s, fail_reason: %d, rx_power_mean_dbm: %f\n",
3410 completed.pon_intf_id, completed.onu_id, completed.status.c_str(), completed.reason, completed.rx_power_mean_dbm);
3411
3412 response->set_intf_id(completed.pon_intf_id);
3413 response->set_onu_id(completed.onu_id);
3414 response->set_status(completed.status);
3415 response->set_fail_reason(static_cast<::openolt::PonRxPowerData_RssiMeasurementFailReason>(completed.reason));
3416 response->set_rx_power_mean_dbm(completed.rx_power_mean_dbm);
3417 }
3418
3419 // Remove entry from map
3420 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3421 onu_rssi_compltd_map.erase(key);
3422 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3423
3424 if (err == BCM_ERR_OK) {
3425 return Status::OK;
3426 } else {
3427 return bcm_to_grpc_err(err, "timeout waiting for pon rssi measurement complete indication");
3428 }
3429}