blob: 600b57f7f3ad090412dbddcccf3b25d9ef40456b [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);
273 pool->set_end(ALLOC_ID_START);
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);
368
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000369 OPENOLT_LOG(INFO, openolt_log_id, "Enable OLT - %s-%s\n", VENDOR_ID, MODEL_ID);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600370
Jason Huangbf45ffb2019-10-30 17:29:02 +0800371 //check BCM daemon is connected or not
372 Status status = check_connection();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000373 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800374 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000375 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800376 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000377 Status status = SubscribeIndication();
378 if (!status.ok()) {
379 OPENOLT_LOG(ERROR, openolt_log_id, "SubscribeIndication failed - %s : %s\n",
380 grpc_status_code_to_string(status.error_code()).c_str(),
381 status.error_message().c_str());
382 return status;
383 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800384
385 //check BAL state in initial stage
386 status = check_bal_ready();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000387 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800388 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000389 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800390 }
391
392 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000393 bcmos_errno err;
394 bcmolt_odid dev;
395 OPENOLT_LOG(INFO, openolt_log_id, "Enabling PON %d Devices ... \n", BCM_MAX_DEVS_PER_LINE_CARD);
396 for (dev = 0; dev < BCM_MAX_DEVS_PER_LINE_CARD; dev++) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400397 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000398 bcmolt_device_key dev_key = { };
399 dev_key.device_id = dev;
400 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
401 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
402 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
Jason Huangbf45ffb2019-10-30 17:29:02 +0800403 if (err == BCM_ERR_NOT_CONNECTED) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000404 bcmolt_device_key key = {.device_id = dev};
405 bcmolt_device_connect oper;
406 BCMOLT_OPER_INIT(&oper, device, connect, key);
Thiyagarajan Subramani3e8bfd92021-04-26 15:07:14 +0530407
408 /* BAL saves current state into dram_tune soc file and when dev_mgmt_daemon restarts
409 * it retains config from soc file. If openolt agent try to connect device without
410 * device reset device initialization fails hence doing device reset here. */
411 reset_pon_device(dev);
412
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000413 if (MODEL_ID == "asfvolt16") {
414 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
415 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_XGS__2_X);
416 } else if (MODEL_ID == "asgvolt64") {
417 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
418 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
419 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
Thiyagarajan Subramani3e8bfd92021-04-26 15:07:14 +0530420 } else if (MODEL_ID == "phoenix") {
421 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_NONE);
422 if(dev == 1) {
423 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
424 }
425 BCMOLT_MSG_FIELD_SET (&oper, ras_ddr_mode, BCMOLT_RAS_DDR_USAGE_MODE_TWO_DDRS);
426 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
427 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000428 }
429 err = bcmolt_oper_submit(dev_id, &oper.hdr);
430 if (err) {
431 failed_enable_device_cnt ++;
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500432 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 +0000433 if (failed_enable_device_cnt == BCM_MAX_DEVS_PER_LINE_CARD) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500434 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 +0000435 return Status(grpc::StatusCode::INTERNAL, "Failed to activate all PON ports");
436 }
437 }
438 bcmos_usleep(200000);
439 }
440 else {
441 OPENOLT_LOG(WARNING, openolt_log_id, "PON deivce %d already connected\n", dev);
442 state.activate();
443 }
444 }
445 init_stats();
Shad Ansari627b5782018-08-13 22:49:32 +0000446 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000447 }
Shad Ansariedef2132018-08-10 22:14:50 +0000448
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000449 /* Start CLI */
450 OPENOLT_LOG(INFO, def_log_id, "Starting CLI\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400451 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000452 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400453}
454
455Status Disable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400456 //In the earlier implementation Disabling olt is done by disabling the NNI port associated with that.
457 //In inband scenario instead of using management interface to establish connection with adapter ,NNI interface will be used.
458 //Disabling NNI port on olt disable causes connection loss between adapter and agent.
459 //To overcome this disable is implemented by disabling all the PON ports
460 //associated with the device so as to support both in-band
461 //and out of band scenarios.
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400462
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400463 Status status;
464 int failedCount = 0;
Girish Gowdrae1db2952021-05-04 00:16:54 -0700465 OPENOLT_LOG(INFO, openolt_log_id, "Received disable OLT\n");
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400466 for (int i = 0; i < NumPonIf_(); i++) {
467 status = DisablePonIf_(i);
468 if (!status.ok()) {
469 failedCount+=1;
470 BCM_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", i);
471 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400472 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400473 if (failedCount == 0) {
474 state.deactivate();
Girish Gowdra252f4972020-09-07 21:24:01 -0700475 ::openolt::Indication ind;
476 ::openolt::OltIndication* olt_ind = new ::openolt::OltIndication;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400477 olt_ind->set_oper_state("down");
478 ind.set_allocated_olt_ind(olt_ind);
479 BCM_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
480 oltIndQ.push(ind);
481 return Status::OK;
482 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000483 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400484 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to disable olt ,all the PON ports are still in enabled state");
485 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400486
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400487 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 -0400488}
489
490Status Reenable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400491 Status status;
492 int failedCount = 0;
493 for (int i = 0; i < NumPonIf_(); i++) {
494 status = EnablePonIf_(i);
495 if (!status.ok()) {
496 failedCount+=1;
497 BCM_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", i);
498 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400499 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000500 if (failedCount == 0) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400501 state.activate();
Girish Gowdra252f4972020-09-07 21:24:01 -0700502 ::openolt::Indication ind;
503 ::openolt::OltIndication* olt_ind = new ::openolt::OltIndication;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400504 olt_ind->set_oper_state("up");
505 ind.set_allocated_olt_ind(olt_ind);
506 BCM_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
507 oltIndQ.push(ind);
508 return Status::OK;
509 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000510 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400511 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to re-enable olt ,all the PON ports are still in disabled state");
512 }
513 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 +0000514}
515
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000516inline uint64_t get_flow_status(uint16_t flow_id, uint16_t flow_type, uint16_t data_id) {
517 bcmos_errno err;
518 bcmolt_flow_key flow_key;
519 bcmolt_flow_cfg flow_cfg;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400520
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000521 flow_key.flow_id = flow_id;
522 flow_key.flow_type = (bcmolt_flow_type)flow_type;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400523
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000524 BCMOLT_CFG_INIT(&flow_cfg, flow, flow_key);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400525
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000526 switch (data_id) {
527 case ONU_ID: //onu_id
528 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, onu_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500529 #ifdef TEST_MODE
530 // It is impossible to mock the setting of flow_cfg.data.state because
531 // the actual bcmolt_cfg_get passes the address of flow_cfg.hdr and we cannot
532 // set the flow_cfg.data. So a new stub function is created and address
533 // of flow_cfg is passed. This is one-of case where we need to add test specific
534 // code in production code.
535 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
536 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000537 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500538 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000539 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500540 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get onu_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000541 return err;
542 }
543 return flow_cfg.data.onu_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400544 case FLOW_TYPE:
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500545 #ifdef TEST_MODE
546 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
547 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000548 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500549 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000550 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500551 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get flow_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000552 return err;
553 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400554 return flow_cfg.key.flow_type;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000555 case SVC_PORT_ID: //svc_port_id
556 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, svc_port_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500557 #ifdef TEST_MODE
558 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
559 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000560 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500561 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000562 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500563 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get svc_port_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000564 return err;
565 }
566 return flow_cfg.data.svc_port_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400567 case PRIORITY:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000568 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, priority);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500569 #ifdef TEST_MODE
570 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
571 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000572 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500573 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000574 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500575 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get priority, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000576 return err;
577 }
578 return flow_cfg.data.priority;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400579 case COOKIE: //cookie
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000580 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, cookie);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500581 #ifdef TEST_MODE
582 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
583 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000584 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500585 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000586 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500587 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get cookie, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000588 return err;
589 }
590 return flow_cfg.data.cookie;
591 case INGRESS_INTF_TYPE: //ingress intf_type
592 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500593 #ifdef TEST_MODE
594 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
595 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000596 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500597 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000598 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500599 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get ingress intf_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000600 return err;
601 }
602 return flow_cfg.data.ingress_intf.intf_type;
603 case EGRESS_INTF_TYPE: //egress intf_type
604 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500605 #ifdef TEST_MODE
606 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
607 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000608 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500609 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000610 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500611 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress intf_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000612 return err;
613 }
614 return flow_cfg.data.egress_intf.intf_type;
615 case INGRESS_INTF_ID: //ingress intf_id
616 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500617 #ifdef TEST_MODE
618 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
619 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000620 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500621 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000622 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500623 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get ingress intf_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000624 return err;
625 }
626 return flow_cfg.data.ingress_intf.intf_id;
627 case EGRESS_INTF_ID: //egress intf_id
628 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500629 #ifdef TEST_MODE
630 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
631 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000632 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500633 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000634 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500635 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress intf_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000636 return err;
637 }
638 return flow_cfg.data.egress_intf.intf_id;
639 case CLASSIFIER_O_VID:
640 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500641 #ifdef TEST_MODE
642 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
643 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000644 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500645 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000646 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500647 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier o_vid, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000648 return err;
649 }
650 return flow_cfg.data.classifier.o_vid;
651 case CLASSIFIER_O_PBITS:
652 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500653 #ifdef TEST_MODE
654 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
655 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000656 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500657 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000658 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500659 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier o_pbits, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000660 return err;
661 }
662 return flow_cfg.data.classifier.o_pbits;
663 case CLASSIFIER_I_VID:
664 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500665 #ifdef TEST_MODE
666 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
667 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000668 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500669 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000670 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500671 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier i_vid, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000672 return err;
673 }
674 return flow_cfg.data.classifier.i_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400675 case CLASSIFIER_I_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000676 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500677 #ifdef TEST_MODE
678 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
679 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000680 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500681 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000682 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500683 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier i_pbits, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000684 return err;
685 }
686 return flow_cfg.data.classifier.i_pbits;
687 case CLASSIFIER_ETHER_TYPE:
688 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500689 #ifdef TEST_MODE
690 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
691 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000692 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500693 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000694 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500695 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier ether_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000696 return err;
697 }
698 return flow_cfg.data.classifier.ether_type;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400699 case CLASSIFIER_IP_PROTO:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000700 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500701 #ifdef TEST_MODE
702 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
703 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000704 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500705 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000706 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500707 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier ip_proto, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000708 return err;
709 }
710 return flow_cfg.data.classifier.ip_proto;
711 case CLASSIFIER_SRC_PORT:
712 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500713 #ifdef TEST_MODE
714 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
715 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000716 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500717 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000718 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500719 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier src_port, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000720 return err;
721 }
722 return flow_cfg.data.classifier.src_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400723 case CLASSIFIER_DST_PORT:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000724 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500725 #ifdef TEST_MODE
726 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
727 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000728 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500729 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000730 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500731 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier dst_port, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000732 return err;
733 }
734 return flow_cfg.data.classifier.dst_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400735 case CLASSIFIER_PKT_TAG_TYPE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000736 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500737 #ifdef TEST_MODE
738 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
739 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000740 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500741 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000742 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500743 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 +0000744 return err;
745 }
746 return flow_cfg.data.classifier.pkt_tag_type;
747 case EGRESS_QOS_TYPE:
748 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500749 #ifdef TEST_MODE
750 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
751 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000752 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500753 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000754 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500755 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000756 return err;
757 }
758 return flow_cfg.data.egress_qos.type;
759 case EGRESS_QOS_QUEUE_ID:
760 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500761 #ifdef TEST_MODE
762 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
763 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000764 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500765 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000766 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500767 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos queue_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000768 return err;
769 }
770 switch (flow_cfg.data.egress_qos.type) {
771 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE:
772 return flow_cfg.data.egress_qos.u.fixed_queue.queue_id;
773 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE:
774 return flow_cfg.data.egress_qos.u.tc_to_queue.tc_to_queue_id;
775 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC:
776 return flow_cfg.data.egress_qos.u.pbit_to_tc.tc_to_queue_id;
777 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE:
778 return flow_cfg.data.egress_qos.u.priority_to_queue.tm_q_set_id;
779 case BCMOLT_EGRESS_QOS_TYPE_NONE:
780 default:
781 return -1;
782 }
783 case EGRESS_QOS_TM_SCHED_ID:
784 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500785 #ifdef TEST_MODE
786 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
787 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000788 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500789 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000790 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500791 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos tm_sched_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000792 return err;
793 }
794 return flow_cfg.data.egress_qos.tm_sched.id;
795 case ACTION_CMDS_BITMASK:
796 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500797 #ifdef TEST_MODE
798 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
799 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000800 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500801 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000802 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500803 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action cmds_bitmask, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000804 return err;
805 }
806 return flow_cfg.data.action.cmds_bitmask;
807 case ACTION_O_VID:
808 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500809 #ifdef TEST_MODE
810 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
811 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000812 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500813 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000814 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500815 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action o_vid, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000816 return err;
817 }
818 return flow_cfg.data.action.o_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400819 case ACTION_O_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000820 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500821 #ifdef TEST_MODE
822 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
823 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000824 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500825 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000826 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500827 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action o_pbits, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000828 return err;
829 }
830 return flow_cfg.data.action.o_pbits;
831 case ACTION_I_VID:
832 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500833 #ifdef TEST_MODE
834 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
835 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000836 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500837 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000838 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500839 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 +0000840 return err;
841 }
842 return flow_cfg.data.action.i_vid;
843 case ACTION_I_PBITS:
844 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500845 #ifdef TEST_MODE
846 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
847 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000848 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500849 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000850 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500851 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 +0000852 return err;
853 }
854 return flow_cfg.data.action.i_pbits;
855 case STATE:
856 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, state);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500857 #ifdef TEST_MODE
858 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
859 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000860 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500861 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000862 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500863 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get state, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000864 return err;
865 }
866 return flow_cfg.data.state;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000867 case GROUP_ID:
868 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, group_id);
869 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
870 if (err) {
871 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get group_id, err = %s\n",bcmos_strerror(err));
872 return err;
873 }
874 return flow_cfg.data.group_id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000875 default:
876 return BCM_ERR_INTERNAL;
877 }
878
879 return err;
880}
881
882Status EnablePonIf_(uint32_t intf_id) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400883 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000884 bcmolt_pon_interface_cfg interface_obj;
885 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
886 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
887 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530888 bcmolt_status los_status;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000889
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530890 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000891 if (err == BCM_ERR_OK) {
892 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800893 OPENOLT_LOG(WARNING, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000894 return Status::OK;
895 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400896 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000897 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
898 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
899 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
900 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.interval, 5000);
901 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.onu_post_discovery_mode,
Girish Gowdra24297032020-03-23 12:32:37 -0700902 BCMOLT_ONU_POST_DISCOVERY_MODE_NONE);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000903 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.los, true);
904 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.onu_alarms, true);
905 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.tiwi, true);
906 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.ack_timeout, true);
907 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.sfi, true);
908 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.loki, true);
Burak Gurdag5e587792020-05-06 14:58:02 +0000909
910 // On GPON, power level mode is not set to its default value (i.e. 0) as documented in Broadcom documentation.
911 // Instead, it is set to 2 which means -6 dbM attenuation. Therefore, we explicitly set it to the default value below.
912 if (board_technology == "GPON") {
913 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.pls_maximum_allocation_size, BCMOLT_PON_POWER_LEVEL_PLS_MAXIMUM_ALLOCATION_SIZE_DEFAULT);
914 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.mode, BCMOLT_PON_POWER_LEVEL_MODE_DEFAULT);
915 }
916
kesavandc1f2db92020-08-31 15:32:06 +0530917 //Enable AES Encryption
918 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.key_exchange, BCMOLT_CONTROL_STATE_ENABLE);
919 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.authentication, BCMOLT_CONTROL_STATE_ENABLE);
920 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.fail_due_to_authentication_failure, BCMOLT_CONTROL_STATE_ENABLE);
921
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000922 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
923 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
924
925 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
926 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500927 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 +0000928 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
929 }
930 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
931 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500932 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 +0000933 return bcm_to_grpc_err(err, "Failed to enable PON interface");
934 }
935 else {
936 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
937 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
938 CreateDefaultSched(intf_id, downstream);
939 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400940 }
941
942 return Status::OK;
943}
944
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500945Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000946 bcmos_errno err;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400947 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000948 bcmolt_device_key dev_key = { };
949 bcmolt_olt_cfg olt_cfg = { };
950 bcmolt_olt_key olt_key = { };
951 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
952 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500953
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000954 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
955 topo.topology_maps.arr = &topo_map[0];
956 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
957 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
958 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400959 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000960 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400961 #ifdef TEST_MODE
962 // It is impossible to mock the setting of olt_cfg.data.bal_state because
963 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
964 // set the olt_cfg.data.topology. So a new stub function is created and address
965 // of olt_cfg is passed. This is one-of case where we need to test add specific
966 // code in production code.
967 err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
968 #else
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000969 err = bcmolt_cfg_get_mult_retry(dev_id, &olt_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400970 #endif
971 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500972 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 +0000973 return bcm_to_grpc_err(err, "cfg: Failed to query OLT topology");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500974 }
975
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000976 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
977 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500978
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400979 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
980 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000981 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500982
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000983 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
984 num_of_nni_ports,
985 num_of_pon_ports,
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400986 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500987
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000988 uint32_t num_failed_cfg_gets = 0;
Jason Huang09b73ea2020-01-08 17:52:05 +0800989 static std::string openolt_version = firmware_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000990 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
991 dev_key.device_id = devid;
992 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
993 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
994 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
995 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000996 err = bcmolt_cfg_get_mult_retry(dev_id, &dev_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400997 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500998 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 +0000999 num_failed_cfg_gets++;
1000 continue;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001001 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001002
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001003 std::string bal_version;
1004 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
1005 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
1006 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
Jason Huang09b73ea2020-01-08 17:52:05 +08001007 firmware_version = "BAL." + bal_version + "__" + openolt_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001008
1009 switch(dev_cfg.data.system_mode) {
1010 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
1011 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
1012 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
1013 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
1014 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
1015 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
1016 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
1017 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
1018 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
1019 case 20: board_technology = MIXED_TECH; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,MIXED_TECH); break;
1020 }
1021
1022 switch(dev_cfg.data.chip_family) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001023 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X: chip_family = "Maple"; break;
1024 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X: chip_family = "Aspen"; break;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001025 }
1026
Jason Huang09b73ea2020-01-08 17:52:05 +08001027 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s, family: %s, board_technology: %s\n",
1028 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 +00001029
1030 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001031 }
1032
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001033 /* 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 +00001034 only the devices that retured success*/
1035 if (num_failed_cfg_gets == BCM_MAX_DEVS_PER_LINE_CARD) {
1036 OPENOLT_LOG(ERROR, openolt_log_id, "device: Query of all the devices failed\n");
1037 return bcm_to_grpc_err(err, "device: All devices failed query");
1038 }
1039
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001040 return Status::OK;
1041}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001042
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001043Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001044 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001045 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
1046 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
1047 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001048
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001049 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001050 if (err == BCM_ERR_OK) {
1051 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001052 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001053 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1054 CreateDefaultSched(intf_id, upstream);
1055 CreateDefaultQueue(intf_id, upstream);
1056 return Status::OK;
1057 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1058 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
1059 return Status::OK;
1060 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001061 }
1062
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001063 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
1064 if (set_state) {
1065 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1066 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1067 } else {
1068 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1069 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1070 }
1071 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
1072 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001073 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err = %s\n",
1074 (set_state)?"enable":"disable", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001075 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
1076 }
1077 else {
1078 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
1079 if (set_state) {
1080 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1081 CreateDefaultSched(intf_id, upstream);
1082 CreateDefaultQueue(intf_id, upstream);
1083 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001084 }
1085
1086 return Status::OK;
1087}
1088
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001089Status DisablePonIf_(uint32_t intf_id) {
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001090 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001091 bcmolt_pon_interface_cfg interface_obj;
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001092 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1093 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001094
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001095 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
Girish Gowdrae1db2952021-05-04 00:16:54 -07001096 BCMOLT_MSG_FIELD_GET(&interface_obj, state);
1097
1098 err = bcmolt_cfg_get(dev_id, &interface_obj.hdr);
1099 if (err != BCM_ERR_OK) {
1100 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);
1101 return bcm_to_grpc_err(err, "Failed to fetch pon port state");
1102 }
1103 if (interface_obj.data.state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1104 OPENOLT_LOG(INFO, openolt_log_id, "PON Interface already inactive, PON interface %d\n", intf_id);
1105 return Status::OK;
1106 }
1107
1108 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001109 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1110 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_DISABLE);
1111
1112 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1113 if (err != BCM_ERR_OK) {
1114 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable discovery of onu, PON interface %d, err %d\n", intf_id, err);
1115 return bcm_to_grpc_err(err, "Failed to disable discovery of onu");
1116 }
1117
1118 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1119 operation, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1120
1121 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1122 if (err != BCM_ERR_OK) {
1123 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 -04001124 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001125 }
1126
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001127 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled PON interface: %d\n", intf_id);
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001128 return Status::OK;
1129}
1130
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001131Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
kesavandc1f2db92020-08-31 15:32:06 +05301132 const char *vendor_id, const char *vendor_specific, uint32_t pir, bool omcc_encryption_mode) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001133 bcmos_errno err = BCM_ERR_OK;
1134 bcmolt_onu_cfg onu_cfg;
1135 bcmolt_onu_key onu_key;
1136 bcmolt_serial_number serial_number; /**< ONU serial number */
1137 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001138
Girish Gowdra24297032020-03-23 12:32:37 -07001139 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1140 bcmolt_onu_state onu_state;
1141
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001142 onu_key.onu_id = onu_id;
1143 onu_key.pon_ni = intf_id;
1144 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1145 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Girish Gowdra24297032020-03-23 12:32:37 -07001146#ifdef TEST_MODE
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001147 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1148 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1149 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1150 // of onu_cfg is passed. This is one-of case where we need to add test specific
1151 // code in production code.
1152 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Girish Gowdra24297032020-03-23 12:32:37 -07001153#else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001154 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Girish Gowdra24297032020-03-23 12:32:37 -07001155#endif
1156 OPENOLT_LOG(INFO, openolt_log_id, "Activate ONU : old state = %d, current state = %d\n",
1157 onu_cfg.data.onu_old_state, onu_cfg.data.onu_state);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001158 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001159 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) {
1160 OPENOLT_LOG(INFO, openolt_log_id, "ONU is already in ACTIVE state, \
1161not processing this request for pon_intf=%d onu_id=%d\n", intf_id, onu_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001162 return Status::OK;
Girish Gowdra24297032020-03-23 12:32:37 -07001163 } else if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_NOT_CONFIGURED &&
1164 onu_cfg.data.onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1165 // We need the ONU to be in NOT_CONFIGURED or INACTIVE state to further process the request
1166 OPENOLT_LOG(ERROR, openolt_log_id, "ONU in an invalid state to process the request, \
1167state=%d pon_intf=%d onu_id=%d\n", onu_cfg.data.onu_state, intf_id, onu_id);
1168 return bcm_to_grpc_err(err, "Failed to activate ONU, invalid ONU state");
1169 }
1170 } else {
1171 // This should never happen. BAL GET should succeed for non-existant ONUs too. The state of such ONUs will be NOT_CONFIGURED
1172 OPENOLT_LOG(ERROR, openolt_log_id, "ONU state query failed pon_intf=%d onu_id=%d\n", intf_id, onu_id);
1173 return bcm_to_grpc_err(err, "onu get failed");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001174 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001175
Girish Gowdra24297032020-03-23 12:32:37 -07001176 // If the ONU is not configured at all we need to first configure it
1177 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_NOT_CONFIGURED) {
1178 OPENOLT_LOG(INFO, openolt_log_id, "Configuring ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001179vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Girish Gowdra24297032020-03-23 12:32:37 -07001180 vendor_specific_to_str(vendor_specific).c_str(), pir);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001181
Girish Gowdra24297032020-03-23 12:32:37 -07001182 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1183 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1184 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1185 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1186 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1187 /*set burst and data profiles to fec disabled*/
1188 if (board_technology == "XGS-PON") {
1189 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1190 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1191 } else if (board_technology == "GPON") {
1192 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1193 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1194 }
1195 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1196 if (err != BCM_ERR_OK) {
1197 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to configure ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
1198 return bcm_to_grpc_err(err, "Failed to configure ONU");
1199 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001200 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001201
Burak Gurdaga0523592021-02-24 15:17:47 +00001202// TODO: MOVE THIS TO A NEW METHOD
kesavandc1f2db92020-08-31 15:32:06 +05301203 if (omcc_encryption_mode == true) {
1204 // set the encryption mode for omci port id
1205 bcmolt_itupon_gem_cfg gem_cfg;
1206 bcmolt_itupon_gem_key key = {};
1207 bcmolt_gem_port_configuration configuration = {};
1208 key.pon_ni = intf_id;
1209 key.gem_port_id = onu_id;
1210 bcmolt_control_state encryption_mode;
1211 encryption_mode = BCMOLT_CONTROL_STATE_ENABLE;
1212 BCMOLT_CFG_INIT(&gem_cfg, itupon_gem, key);
1213 BCMOLT_FIELD_SET(&gem_cfg.data, itupon_gem_cfg_data, encryption_mode, encryption_mode);
1214 err = bcmolt_cfg_set(dev_id, &gem_cfg.hdr);
1215 if(err != BCM_ERR_OK) {
Burak Gurdaga0523592021-02-24 15:17:47 +00001216 OPENOLT_LOG(ERROR, openolt_log_id, "failed to configure omci gem_port encryption mode = %d\n", onu_id);
kesavandc1f2db92020-08-31 15:32:06 +05301217 return bcm_to_grpc_err(err, "Access_Control set ITU PON OMCI Gem port failed");
1218 }
1219 }
Girish Gowdra24297032020-03-23 12:32:37 -07001220 // Now that the ONU is configured, move the ONU to ACTIVE state
1221 memset(&onu_cfg, 0, sizeof(bcmolt_onu_cfg));
1222 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1223 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1224 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
1225 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
1226 onu_state, BCMOLT_ONU_OPERATION_ACTIVE);
1227 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001228 if (err != BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001229 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 +00001230 return bcm_to_grpc_err(err, "Failed to activate ONU");
1231 }
Girish Gowdra24297032020-03-23 12:32:37 -07001232 // ONU will eventually get activated after we have submitted the operation request. The adapter will receive an asynchronous
1233 // ONU_ACTIVATION_COMPLETED_INDICATION
1234
1235 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 +00001236
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001237 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001238}
1239
Jonathan Davis70c21812018-07-19 15:32:10 -04001240Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1241 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001242 bcmos_errno err = BCM_ERR_OK;
1243 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1244 bcmolt_onu_cfg onu_cfg;
1245 bcmolt_onu_key onu_key; /**< Object key. */
1246 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001247
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001248 onu_key.onu_id = onu_id;
1249 onu_key.pon_ni = intf_id;
1250 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1251 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001252 #ifdef TEST_MODE
1253 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1254 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1255 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1256 // of onu_cfg is passed. This is one-of case where we need to add test specific
1257 // code in production code.
1258 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001259 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001260 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001261 #endif
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301262 onu_state = onu_cfg.data.onu_state;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001263 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001264 switch (onu_state) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001265 case BCMOLT_ONU_STATE_ACTIVE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001266 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001267 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001268 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1269 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1270 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001271 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 +00001272 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1273 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301274 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 +00001275 break;
1276 }
Jonathan Davis70c21812018-07-19 15:32:10 -04001277 }
1278
1279 return Status::OK;
1280}
1281
1282Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001283 const char *vendor_id, const char *vendor_specific) {
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301284 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301285 bcmolt_onu_state onu_state;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001286
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001287 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 -05001288 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1289
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001290 // Need to deactivate before removing it (BAL rules)
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001291 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301292
1293 err = get_onu_status((bcmolt_interface)intf_id, onu_id, &onu_state);
1294 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001295 if (onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1296 OPENOLT_LOG(INFO, openolt_log_id, "waiting for onu deactivate complete response: intf_id=%d, onu_id=%d\n",
1297 intf_id, onu_id);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301298 err = wait_for_onu_deactivate_complete(intf_id, onu_id);
1299 if (err) {
1300 OPENOLT_LOG(ERROR, openolt_log_id, "failed to delete onu intf_id %d, onu_id %d\n",
1301 intf_id, onu_id);
1302 return bcm_to_grpc_err(err, "Failed to delete ONU");
1303 }
1304 }
Girish Gowdra24297032020-03-23 12:32:37 -07001305 else {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301306 OPENOLT_LOG(INFO, openolt_log_id, "Onu is Inactive, onu_id: %d, not waiting for onu deactivate complete response\n",
1307 intf_id);
1308 }
1309 }
1310 else {
1311 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch Onu status, onu_id = %d, intf_id = %d, err = %s\n",
1312 onu_id, intf_id, bcmos_strerror(err));
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301313 return bcm_to_grpc_err(err, "Failed to delete ONU");
1314 }
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001315
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001316 bcmolt_onu_cfg cfg_obj;
1317 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001318
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001319 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 -04001320 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001321
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001322 key.onu_id = onu_id;
1323 key.pon_ni = intf_id;
1324 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001325
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301326 err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001327 if (err != BCM_ERR_OK)
1328 {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001329 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 -04001330 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1331 }
1332
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301333 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 +00001334 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001335}
1336
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001337#define MAX_CHAR_LENGTH 20
1338#define MAX_OMCI_MSG_LENGTH 44
1339Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001340 bcmolt_bin_str buf = {};
1341 bcmolt_onu_cpu_packets omci_cpu_packets;
1342 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001343
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001344 key.pon_ni = intf_id;
1345 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001346
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001347 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1348 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1349 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001350
1351 // ???
1352 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1353 buf.len = MAX_OMCI_MSG_LENGTH;
1354 } else {
1355 buf.len = pkt.size()/2;
1356 }
1357
1358 /* Send the OMCI packet using the BAL remote proxy API */
1359 uint16_t idx1 = 0;
1360 uint16_t idx2 = 0;
1361 uint8_t arraySend[buf.len];
1362 char str1[MAX_CHAR_LENGTH];
1363 char str2[MAX_CHAR_LENGTH];
1364 memset(&arraySend, 0, buf.len);
1365
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001366 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1367 sprintf(str1,"%c", pkt[idx1]);
1368 sprintf(str2,"%c", pkt[++idx1]);
1369 strcat(str1,str2);
1370 arraySend[idx2] = strtol(str1, NULL, 16);
1371 }
1372
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001373 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1374 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001375
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001376 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1377 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1378 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001379
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001380 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001381 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001382 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 +00001383 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001384 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001385 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 -05001386 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001387 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001388 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001389
1390 return Status::OK;
1391}
1392
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001393Status 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 +00001394 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1395 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1396 bcmolt_bin_str buf = {};
1397 bcmolt_gem_port_id gem_port_id_array[1];
1398 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001399
Craig Lutgen967a1d02018-11-27 10:41:51 -06001400 if (port_no > 0) {
1401 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001402 if (gemport_id == 0) {
1403 bcmos_fastlock_lock(&data_lock);
1404 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1405 // Pick any flow that is mapped with the same port_no.
1406 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1407 if (it != port_to_flows.end() && !it->second.empty()) {
1408 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1409 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1410 if (fit != flowid_to_gemport.end()) {
1411 found = true;
1412 gemport_id = fit->second;
1413 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001414 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001415 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001416
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001417 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001418 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 -08001419 onu_id, port_no, intf_id);
1420 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1421 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001422 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 -08001423 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001424 }
1425
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001426 gem_port_id_array[0] = gemport_id;
1427 gem_port_list.len = 1;
1428 gem_port_list.arr = gem_port_id_array;
1429 buf.len = pkt.size();
1430 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1431 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1432
1433 /* init the API struct */
1434 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1435 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1436 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1437 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1438 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1439
1440 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1441 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1442
1443 /* call API */
1444 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001445 }
1446 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001447 //TODO: Port No is 0, it is coming sender requirement.
1448 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1449 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001450 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001451 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001452
1453 return Status::OK;
1454}
1455
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001456Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001457 bcmolt_flow_key key = {}; /* declare key */
1458 bcmolt_bin_str buffer = {};
1459 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001460
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001461 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
Girish Gowdra252f4972020-09-07 21:24:01 -07001462 bcmolt_flow_id flow_id = INVALID_FLOW_ID;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001463
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001464 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1465 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1466 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1467 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1468 key.flow_id = flow_id;
1469 else {
Jason Huang09b73ea2020-01-08 17:52:05 +08001470 if (flow_id_counters) {
1471 std::map<flow_pair, int>::iterator it;
1472 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1473 int flow_index = it->first.first;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001474 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1475 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1476 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1477 key.flow_id = flow_index;
1478 break;
1479 }
1480 }
1481 }
1482 else {
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001483 OPENOLT_LOG(ERROR, openolt_log_id, "no flow id found for uplink packetout\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001484 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1485 }
1486 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001487
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001488 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001489
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001490 /* Initialize the API struct. */
1491 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001492
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001493 buffer.len = pkt.size();
1494 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1495 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1496 if (buffer.arr == NULL) {
1497 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1498 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1499 }
1500 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1501
1502 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1503 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001504 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 -05001505 return bcm_to_grpc_err(BCM_ERR_SYSCALL_ERR, "Error sending packets via nni port");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001506 } else {
1507 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1508 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001509
1510 return Status::OK;
1511}
Girish Gowdra252f4972020-09-07 21:24:01 -07001512
Burak Gurdaga0523592021-02-24 15:17:47 +00001513bool get_aes_flag_for_gem_port(const google::protobuf::Map<unsigned int, bool> &gemport_to_aes, uint32_t gemport_id) {
1514 bool aes_flag = false;
1515 for (google::protobuf::Map<unsigned int, bool>::const_iterator it=gemport_to_aes.begin(); it!=gemport_to_aes.end(); it++) {
1516 if (it->first == gemport_id) {
1517 aes_flag = it->second;
1518 break;
1519 }
1520 }
1521 return aes_flag;
1522}
1523
Girish Gowdra252f4972020-09-07 21:24:01 -07001524Status FlowAddWrapper_(const ::openolt::Flow* request) {
1525
1526 int32_t access_intf_id = request->access_intf_id();
1527 int32_t onu_id = request->onu_id();
1528 int32_t uni_id = request->uni_id();
1529 uint32_t port_no = request->port_no();
1530 uint64_t voltha_flow_id = request->flow_id();
1531 uint64_t symmetric_voltha_flow_id = request->symmetric_flow_id();
1532 const std::string flow_type = request->flow_type();
1533 int32_t alloc_id = request->alloc_id();
1534 int32_t network_intf_id = request->network_intf_id();
1535 int32_t gemport_id = request->gemport_id();
1536 const ::openolt::Classifier& classifier = request->classifier();
1537 const ::openolt::Action& action = request->action();
1538 int32_t priority = request->priority();
1539 uint64_t cookie = request->cookie();
1540 int32_t group_id = request->group_id();
1541 uint32_t tech_profile_id = request->tech_profile_id();
1542 bool replicate_flow = request->replicate_flow();
1543 const google::protobuf::Map<unsigned int, unsigned int> &pbit_to_gemport = request->pbit_to_gemport();
Burak Gurdaga0523592021-02-24 15:17:47 +00001544 const google::protobuf::Map<unsigned int, bool> &gemport_to_aes = request->gemport_to_aes();
Girish Gowdra252f4972020-09-07 21:24:01 -07001545 uint16_t flow_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001546 bool enable_encryption;
Girish Gowdra252f4972020-09-07 21:24:01 -07001547
1548 // The intf_id variable defaults to access(PON) interface ID.
1549 // For trap-from-nni flow where access interface ID is not valid , change it to NNI interface ID
1550 // This intf_id identifies the pool from which we get the flow_id
1551 uint32_t intf_id = access_intf_id;
1552 if (onu_id < 1) {
1553 onu_id = 1;
1554 }
1555 if (access_intf_id < 0) {
1556 intf_id = network_intf_id;
1557 }
1558
1559 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)
1560 // This is the case of voltha_flow_id (not symmetric_voltha_flow_id)
1561 if (is_voltha_flow_installed(voltha_flow_id)) {
1562 OPENOLT_LOG(INFO, openolt_log_id, "voltha_flow_id=%lu, already installed\n", voltha_flow_id);
1563 return ::Status(grpc::StatusCode::ALREADY_EXISTS, "voltha-flow-already-installed");
1564 }
1565
Girish Gowdra252f4972020-09-07 21:24:01 -07001566 // This is the case of symmetric_voltha_flow_id
1567 // If symmetric_voltha_flow_id is available and valid in the Flow message,
1568 // check if it is installed, and use the corresponding device_flow_id
1569 if (symmetric_voltha_flow_id > 0 && is_voltha_flow_installed(symmetric_voltha_flow_id)) { // symmetric flow found
1570 OPENOLT_LOG(INFO, openolt_log_id, "symmetric flow and the symmetric flow is installed\n");
1571 const device_flow_params *dev_fl_symm_params;
1572 dev_fl_symm_params = get_device_flow_params(symmetric_voltha_flow_id);
1573 if (dev_fl_symm_params == NULL) {
1574 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)
1575 return ::Status(grpc::StatusCode::INTERNAL, "symmetric-flow-details-not-found");
1576 }
1577
1578 if (!replicate_flow) { // No flow replication
1579 flow_id = dev_fl_symm_params[0].flow_id;
1580 gemport_id = dev_fl_symm_params[0].gemport_id; // overwrite the gemport with symmetric flow gemport
1581 // Should be same as what is coming in this request.
Burak Gurdaga0523592021-02-24 15:17:47 +00001582 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001583 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1584 cl.set_o_pbits(dev_fl_symm_params[0].pbit);
1585 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1586 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001587 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001588 if (st.error_code() == grpc::StatusCode::OK) {
1589 device_flow dev_fl;
1590 dev_fl.is_flow_replicated = false;
1591 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1592 dev_fl.voltha_flow_id = voltha_flow_id;
1593 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params));
1594 // update voltha flow to cache
1595 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1596 }
1597 return st;
1598 } else { // Flow to be replicated
1599 OPENOLT_LOG(INFO, openolt_log_id,"symmetric flow and replication is needed\n");
1600 for (uint8_t i=0; i<NUMBER_OF_REPLICATED_FLOWS; i++) {
1601 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1602 flow_id = dev_fl_symm_params[i].flow_id;
1603 gemport_id = dev_fl_symm_params[i].gemport_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001604 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001605 cl.set_o_pbits(dev_fl_symm_params[i].pbit);
1606 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdrade65ab42020-12-17 23:08:43 -08001607 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001608 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001609 if (st.error_code() != grpc::StatusCode::OK && st.error_code() != grpc::StatusCode::ALREADY_EXISTS) {
1610 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);
1611 // On failure remove any successfully replicated flows installed so far for the voltha_flow_id
1612 if (i > 0) {
1613 for (int8_t j = i-1; j >= 0; j--) {
1614 flow_id = dev_fl_symm_params[j].flow_id;
1615 FlowRemove_(flow_id, flow_type);
1616 }
1617 }
1618 return st;
1619 }
1620 }
1621 device_flow dev_fl;
1622 dev_fl.is_flow_replicated = true;
1623 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1624 dev_fl.voltha_flow_id = voltha_flow_id;
1625 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params)*NUMBER_OF_REPLICATED_FLOWS);
1626 // update voltha flow to cache
1627 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1628 }
1629 } else { // No symmetric flow found
1630 if (!replicate_flow) { // No flow replication
1631 OPENOLT_LOG(INFO, openolt_log_id, "not a symmetric flow and replication is not needed\n");
1632 flow_id = get_flow_id();
1633 if (flow_id == INVALID_FLOW_ID) {
1634 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocated flow id for voltha-flow-id=%lu\n", voltha_flow_id);
1635 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1636 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001637 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001638 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1639 flow_type, alloc_id, network_intf_id, gemport_id, classifier,
Burak Gurdaga0523592021-02-24 15:17:47 +00001640 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001641 if (st.error_code() == grpc::StatusCode::OK) {
1642 device_flow dev_fl;
1643 dev_fl.is_flow_replicated = false;
1644 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // Invalid
1645 dev_fl.voltha_flow_id = voltha_flow_id;
1646 dev_fl.params[0].flow_id = flow_id;
1647 dev_fl.params[0].gemport_id = gemport_id;
1648 dev_fl.params[0].pbit = classifier.o_pbits();
1649 // update voltha flow to cache
1650 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1651 } else {
1652 // Free the flow id on failure
1653 free_flow_id(flow_id);
1654 }
1655 return st;
1656 } else { // Flow to be replicated
1657 OPENOLT_LOG(INFO, openolt_log_id,"not a symmetric flow and replication is needed\n");
1658 if (pbit_to_gemport.size() != NUMBER_OF_PBITS) {
1659 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pbit-to-gemport map size=%lu", pbit_to_gemport.size())
1660 return ::Status(grpc::StatusCode::OUT_OF_RANGE, "pbit-to-gemport-map-len-invalid-for-flow-replication");
1661 }
1662 uint16_t flow_ids[NUMBER_OF_REPLICATED_FLOWS];
1663 device_flow dev_fl;
1664 if (get_flow_ids(NUMBER_OF_REPLICATED_FLOWS, flow_ids)) {
1665 uint8_t cnt = 0;
1666 dev_fl.is_flow_replicated = true;
1667 dev_fl.voltha_flow_id = voltha_flow_id;
1668 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // invalid
1669 for (google::protobuf::Map<unsigned int, unsigned int>::const_iterator it=pbit_to_gemport.begin(); it!=pbit_to_gemport.end(); it++) {
1670 dev_fl.params[cnt].flow_id = flow_ids[cnt];
1671 dev_fl.params[cnt].pbit = it->first;
1672 dev_fl.params[cnt].gemport_id = it->second;
1673
1674 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1675 flow_id = dev_fl.params[cnt].flow_id;
1676 gemport_id = dev_fl.params[cnt].gemport_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001677 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001678 cl.set_o_pbits(dev_fl.params[cnt].pbit);
1679 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1680 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001681 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001682 if (st.error_code() != grpc::StatusCode::OK) {
1683 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);
1684 // Remove any successfully replicated flows installed so far for the voltha_flow_id
1685 if (cnt > 0) {
1686 for (int8_t j = cnt-1; j >= 0; j--) {
1687 flow_id = dev_fl.params[j].flow_id;
1688 FlowRemove_(flow_id, flow_type);
1689 }
1690 }
1691 // Free up all the flow IDs on failure
1692 free_flow_ids(NUMBER_OF_REPLICATED_FLOWS, flow_ids);
1693 return st;
1694 }
1695 cnt++;
1696 }
1697 // On successful flow replication update voltha-flow-id to device-flow map to cache
1698 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1699 } else {
1700 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocate flow ids for replication voltha-flow-id=%lu\n", voltha_flow_id);
1701 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1702 }
1703 }
1704 }
1705
1706 return Status::OK;
1707}
1708
1709
Craig Lutgen967a1d02018-11-27 10:41:51 -06001710Status 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 +00001711 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001712 int32_t alloc_id, int32_t network_intf_id,
1713 int32_t gemport_id, const ::openolt::Classifier& classifier,
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001714 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie,
Burak Gurdaga0523592021-02-24 15:17:47 +00001715 int32_t group_id, uint32_t tech_profile_id, bool aes_enabled) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001716 bcmolt_flow_cfg cfg;
1717 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001718 int32_t o_vid = -1;
1719 bool single_tag = false;
1720 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001721 bcmolt_classifier c_val = { };
1722 bcmolt_action a_val = { };
1723 bcmolt_tm_queue_ref tm_val = { };
1724 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05001725 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001726
Jason Huang09b73ea2020-01-08 17:52:05 +08001727 OPENOLT_LOG(INFO, openolt_log_id, "flow add received for flow_id=%u, flow_type=%s\n", flow_id, flow_type.c_str());
1728
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001729 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001730 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001731 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001732 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001733 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001734 } else if (flow_type.compare(multicast) == 0) {
1735 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001736 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001737 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001738 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001739 }
1740
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001741 BCMOLT_CFG_INIT(&cfg, flow, key);
1742 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001743
Jason Huang09b73ea2020-01-08 17:52:05 +08001744 if (action.cmd().trap_to_host()) {
Girish Gowdra1935e6a2020-10-31 21:48:22 -07001745 Status resp = handle_acl_rule_install(onu_id, flow_id, gemport_id, flow_type, access_intf_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001746 network_intf_id, classifier);
Jason Huang09b73ea2020-01-08 17:52:05 +08001747 return resp;
1748 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001749
1750 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1751
1752 if (access_intf_id >= 0 && network_intf_id >= 0) {
1753 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1754 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1755 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08001756 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1757 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001758 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1759 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1760 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1761 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1762 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001763 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001764 } else {
1765 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
1766 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001767 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001768
Burak Gurdaga0523592021-02-24 15:17:47 +00001769 if (onu_id >= ONU_ID_START) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001770 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
1771 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001772 if (gemport_id >= GEM_PORT_ID_START) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001773 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
1774 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001775 if (gemport_id >= GEM_PORT_ID_START && port_no != 0) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001776 bcmos_fastlock_lock(&data_lock);
1777 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
1778 port_to_flows[port_no].insert(key.flow_id);
1779 flowid_to_gemport[key.flow_id] = gemport_id;
1780 }
1781 else
1782 {
1783 flowid_to_port[key.flow_id] = port_no;
1784 }
1785 bcmos_fastlock_unlock(&data_lock, 0);
1786 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001787
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001788 if (priority_value >= 0) {
1789 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
1790 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301791
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001792 } else { // MULTICAST FLOW
1793 if (group_id >= 0) {
1794 BCMOLT_MSG_FIELD_SET(&cfg, group_id, group_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001795 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001796 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1797 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001798 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001799
1800 {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001801 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001802 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001803 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
1804 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001805 }
1806
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001807 if (classifier.dst_mac().size() > 0) {
1808 bcmos_mac_address d_mac = {};
1809 bcmos_mac_address_init(&d_mac);
1810 memcpy(d_mac.u8, classifier.dst_mac().data(), sizeof(d_mac.u8));
1811 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_mac %02x:%02x:%02x:%02x:%02x:%02x\n", d_mac.u8[0],
1812 d_mac.u8[1], d_mac.u8[2], d_mac.u8[3], d_mac.u8[4], d_mac.u8[5]);
1813 BCMOLT_FIELD_SET(&c_val, classifier, dst_mac, d_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001814 }
1815
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001816 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001817 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001818 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001819 }
1820 */
1821
1822 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001823 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
1824 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001825 }
1826
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001827 if (classifier.dst_ip()) {
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08001828 bcmos_ipv4_address d_ip = {};
1829 bcmos_ipv4_address_init(&d_ip);
1830 d_ip.u32 = classifier.dst_ip();
1831 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_ip %04x\n", d_ip.u32);
1832 BCMOLT_FIELD_SET(&c_val, classifier, dst_ip, d_ip);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001833 }
1834
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08001835 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001836 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001837 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001838 }
1839 */
1840
1841 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001842 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
1843 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001844 }
1845
1846 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001847 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
1848 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001849 }
1850
1851 if (!classifier.pkt_tag_type().empty()) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001852 if (classifier.o_vid()) {
1853 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
1854 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
1855 }
1856
1857 if (classifier.i_vid()) {
1858 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
1859 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
1860 }
1861
1862 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
1863 if (classifier.pkt_tag_type().compare("untagged") == 0) {
1864 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
1865 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
1866 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
1867 single_tag = true;
1868
1869 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301870 // OpenOlt adapter will send 0xFF in case of no pbit classification
1871 // If it is any other value (0 to 7), it is for outer pbit classification.
1872 // OpenFlow protocol does not provide inner pbit classification (in case of double tagged packets),
1873 // and VOLTHA has not used any workaround to solve this problem (for ex: use metadata field).
1874 // Also there exists no use case for i-pbit classification, so we can safely ignore this for now.
1875 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001876 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301877 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001878 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
1879 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001880
Jason Huang09b73ea2020-01-08 17:52:05 +08001881 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301882 // Same comments as in case of "single_tag" packets.
1883 // 0xFF means no pbit classification, otherwise a valid PCP (0 to 7).
1884 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001885 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301886 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001887 }
1888 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001889 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001890 }
1891
Jason Huang09b73ea2020-01-08 17:52:05 +08001892 const ::openolt::ActionCmd& cmd = action.cmd();
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001893
Jason Huang09b73ea2020-01-08 17:52:05 +08001894 if (cmd.add_outer_tag()) {
1895 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
1896 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001897 }
1898
Jason Huang09b73ea2020-01-08 17:52:05 +08001899 if (cmd.remove_outer_tag()) {
1900 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
1901 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
1902 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301903
Jason Huang09b73ea2020-01-08 17:52:05 +08001904 if (action.o_vid()) {
1905 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
1906 o_vid = action.o_vid();
1907 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
1908 }
1909
1910 if (action.o_pbits()) {
1911 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
1912 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
1913 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301914
Jason Huang09b73ea2020-01-08 17:52:05 +08001915 if (action.i_vid()) {
1916 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
1917 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
1918 }
1919
1920 if (action.i_pbits()) {
1921 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
1922 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
1923 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301924
Jason Huang09b73ea2020-01-08 17:52:05 +08001925 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
1926
Burak Gurdaga0523592021-02-24 15:17:47 +00001927 if ((access_intf_id >= 0) && (onu_id >= ONU_ID_START)) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001928 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
1929 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00001930 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 +00001931
Jason Huang09b73ea2020-01-08 17:52:05 +08001932 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1933 // Queue 0 on DS subscriber scheduler
1934 tm_val.queue_id = 0;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001935
Jason Huang09b73ea2020-01-08 17:52:05 +08001936 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1937 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1938 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001939
Jason Huang09b73ea2020-01-08 17:52:05 +08001940 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1941 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1942 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001943
Jason Huang09b73ea2020-01-08 17:52:05 +08001944 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1945 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
1946 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 +00001947
Jason Huang09b73ea2020-01-08 17:52:05 +08001948 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1949 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1950 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1951 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 +00001952
Jason Huang09b73ea2020-01-08 17:52:05 +08001953 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
1954 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1955 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1956 }
1957 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
1958 // NNI Scheduler ID
1959 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1960 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1961 // Queue 0 on NNI scheduler
1962 tm_val.queue_id = 0;
1963 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1964 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1965 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001966
Jason Huang09b73ea2020-01-08 17:52:05 +08001967 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 +00001968 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1969 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1970
Jason Huang09b73ea2020-01-08 17:52:05 +08001971 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1972 /* Fetch TM QMP ID mapped to US NNI scheduler */
1973 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
1974 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1975 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1976 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1977 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 +00001978
Jason Huang09b73ea2020-01-08 17:52:05 +08001979 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 +00001980 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1981 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001982 }
Shad Ansari39739bc2018-09-13 21:38:37 +00001983 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301984 } else {
1985 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1986 tm_val.queue_id = 0;
1987
1988 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
1989 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1990 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
1991
1992 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1993 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
1994 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00001995 }
1996
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001997 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001998
Girish Gowdra252f4972020-09-07 21:24:01 -07001999#ifndef SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002000 // BAL 3.1 supports statistics only for unicast flows.
2001 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
2002 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
2003 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002004#endif // SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002005
Girish Gowdra252f4972020-09-07 21:24:01 -07002006#ifndef SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002007#ifdef FLOW_CHECKER
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002008 //Flow Checker, To avoid duplicate flow.
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002009 if (flow_id_counters != 0) {
2010 bool b_duplicate_flow = false;
Jason Huang09b73ea2020-01-08 17:52:05 +08002011 std::map<flow_pair, int>::iterator it;
2012
2013 for(it = flow_map.begin(); it != flow_map.end(); it++) {
2014 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(it->first.first, it->first.second, ONU_ID)) && \
2015 (key.flow_type == it->first.second) && \
2016 (cfg.data.svc_port_id == get_flow_status(it->first.first, it->first.second, SVC_PORT_ID)) && \
2017 (cfg.data.priority == get_flow_status(it->first.first, it->first.second, PRIORITY)) && \
2018 (cfg.data.cookie == get_flow_status(it->first.first, it->first.second, COOKIE)) && \
2019 (cfg.data.ingress_intf.intf_type == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_TYPE)) && \
2020 (cfg.data.ingress_intf.intf_id == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_ID)) && \
2021 (cfg.data.egress_intf.intf_type == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_TYPE)) && \
2022 (cfg.data.egress_intf.intf_id == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_ID)) && \
2023 (c_val.o_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_VID)) && \
2024 (c_val.o_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_PBITS)) && \
2025 (c_val.i_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_VID)) && \
2026 (c_val.i_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_PBITS)) && \
2027 (c_val.ether_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_ETHER_TYPE)) && \
2028 (c_val.ip_proto == get_flow_status(it->first.first, it->first.second, CLASSIFIER_IP_PROTO)) && \
2029 (c_val.src_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_SRC_PORT)) && \
2030 (c_val.dst_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_DST_PORT)) && \
2031 (c_val.pkt_tag_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_PKT_TAG_TYPE)) && \
2032 (cfg.data.egress_qos.type == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TYPE)) && \
2033 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_QUEUE_ID)) && \
2034 (cfg.data.egress_qos.tm_sched.id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TM_SCHED_ID)) && \
2035 (a_val.cmds_bitmask == get_flow_status(it->first.first, it->first.second, ACTION_CMDS_BITMASK)) && \
2036 (a_val.o_vid == get_flow_status(it->first.first, it->first.second, ACTION_O_VID)) && \
2037 (a_val.i_vid == get_flow_status(it->first.first, it->first.second, ACTION_I_VID)) && \
2038 (a_val.o_pbits == get_flow_status(it->first.first, it->first.second, ACTION_O_PBITS)) && \
2039 (a_val.i_pbits == get_flow_status(it->first.first, it->first.second, ACTION_I_PBITS)) && \
2040 (cfg.data.state == get_flow_status(it->first.first, it->first.second, STATE)) && \
2041 (cfg.data.group_id == get_flow_status(it->first.first, it->first.second, GROUP_ID));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002042#ifdef SHOW_FLOW_PARAM
2043 // Flow Parameter
2044 FLOW_PARAM_LOG();
2045#endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002046 if (b_duplicate_flow) {
2047 FLOW_LOG(WARNING, "Flow duplicate", 0);
2048 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
2049 }
2050 }
2051 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002052#endif // FLOW_CHECKER
2053#endif // SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002054
2055 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2056 if (err) {
2057 FLOW_LOG(ERROR, "Flow add failed", err);
2058 return bcm_to_grpc_err(err, "flow add failed");
2059 } else {
2060 FLOW_LOG(INFO, "Flow add ok", err);
2061 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002062 flow_map[std::pair<int, int>(key.flow_id,key.flow_type)] = flow_map.size();
2063 flow_id_counters = flow_map.size();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002064 bcmos_fastlock_unlock(&data_lock, 0);
Girish Gowdra252f4972020-09-07 21:24:01 -07002065
2066 }
Burak Gurdaga0523592021-02-24 15:17:47 +00002067
2068 /*
2069 Enable AES encryption on GEM ports if they are used in downstream unicast flows.
2070 Rationale: We can't do upstream encryption in GPON. This change addresses the common denominator (and also minimum viable)
2071 use case for both technologies which is downstream unicast GEM port encryption. Since the downstream traffic is inherently
2072 broadcast to all the ONUs behind a PON port, encrypting the individual subscriber traffic in this direction is important
2073 and considered good enough in terms of security (See Section 12.1 of G.984.3). For upstream unicast and downstream multicast
2074 GEM encryption, we need to make additional changes specific to XGSPON. This will be done as a future work.
2075 */
2076 if (aes_enabled && (access_intf_id >= 0) && (gemport_id >= GEM_PORT_ID_START) && (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM)) {
2077 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);
2078 enable_encryption_for_gem_port(access_intf_id, gemport_id);
2079 } else {
2080 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);
2081 }
2082
Girish Gowdra252f4972020-09-07 21:24:01 -07002083 return Status::OK;
2084}
2085
2086Status FlowRemoveWrapper_(const ::openolt::Flow* request) {
2087 const std::string flow_type = request->flow_type();
2088 uint64_t voltha_flow_id = request->flow_id();
2089 Status st;
2090
2091 // If Voltha flow is not installed, return fail
2092 if (! is_voltha_flow_installed(voltha_flow_id)) {
2093 OPENOLT_LOG(ERROR, openolt_log_id, "voltha_flow_id=%lu not found\n", voltha_flow_id);
2094 return ::Status(grpc::StatusCode::NOT_FOUND, "voltha-flow-not-found");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002095 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04002096
Girish Gowdra252f4972020-09-07 21:24:01 -07002097 const device_flow *dev_fl = get_device_flow(voltha_flow_id);
2098 if (dev_fl == NULL) {
2099 OPENOLT_LOG(ERROR, openolt_log_id, "device flow for voltha_flow_id=%lu in the cache is NULL\n", voltha_flow_id);
2100 return ::Status(grpc::StatusCode::INTERNAL, "device-flow-null-in-cache");
2101 }
2102 if (dev_fl->is_flow_replicated) {
2103 // Note: Here we are ignoring FlowRemove failures
2104 for (int i=0; i<NUMBER_OF_REPLICATED_FLOWS; i++) {
2105 st = FlowRemove_(dev_fl->params[i].flow_id, flow_type);
2106 if (st.error_code() == grpc::StatusCode::OK) {
2107 free_flow_id(dev_fl->params[i].flow_id);
2108 }
2109 }
2110 } else {
2111 // Note: Here we are ignoring FlowRemove failures
2112 st = FlowRemove_(dev_fl->params[0].flow_id, flow_type);
2113 if (st.error_code() == grpc::StatusCode::OK) {
2114 free_flow_id(dev_fl->params[0].flow_id);
2115 }
2116 }
2117 // remove the flow from cache on voltha flow removal
2118 remove_voltha_flow_from_cache(voltha_flow_id);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002119 return Status::OK;
2120}
2121
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002122Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
2123
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002124 bcmolt_flow_cfg cfg;
2125 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002126
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002127 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002128 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002129 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002130 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002131 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002132 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002133 } else if(flow_type.compare(multicast) == 0) {
2134 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002135 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002136 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002137 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
2138 }
2139
Jason Huang09b73ea2020-01-08 17:52:05 +08002140 OPENOLT_LOG(INFO, openolt_log_id, "flow remove received for flow_id=%u, flow_type=%s\n",
2141 flow_id, flow_type.c_str());
2142
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002143 bcmos_fastlock_lock(&acl_packet_trap_handler_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002144 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
2145 int32_t gemport_id = -1;
2146 int32_t intf_id = -1;
2147 int16_t acl_id = -1;
2148 if (flow_to_acl_map.count(fl_id_fl_dir) > 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002149
2150 acl_id_intf_id ac_id_if_id = flow_to_acl_map[fl_id_fl_dir];
2151 acl_id = std::get<0>(ac_id_if_id);
2152 intf_id = std::get<1>(ac_id_if_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002153 // cleanup acl only if it is a valid acl. If not valid acl, it may be datapath flow.
2154 if (acl_id >= 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002155 Status resp = handle_acl_rule_cleanup(acl_id, intf_id, flow_type);
Jason Huang09b73ea2020-01-08 17:52:05 +08002156 if (resp.ok()) {
2157 OPENOLT_LOG(INFO, openolt_log_id, "acl removed ok for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2158 flow_to_acl_map.erase(fl_id_fl_dir);
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002159
2160 // 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
2161 if (trap_to_host_pkt_info_with_vlan_for_flow_id.count(flow_id) > 0) {
2162 trap_to_host_pkt_info_with_vlan pkt_info_with_vlan = trap_to_host_pkt_info_with_vlan_for_flow_id[flow_id];
2163 // Formulate the trap_to_host_pkt_info tuple key
2164 trap_to_host_pkt_info pkt_info(std::get<0>(pkt_info_with_vlan),
2165 std::get<1>(pkt_info_with_vlan),
2166 std::get<2>(pkt_info_with_vlan),
2167 std::get<3>(pkt_info_with_vlan));
2168 // Extract the value corresponding to trap_to_host_pkt_info key from trap_to_host_vlan_ids_for_trap_to_host_pkt_info
2169 // The value is a list of vlan_ids for the given trap_to_host_pkt_info key
2170 // Remove the vlan_id from the list that corresponded to the flow being removed.
2171 if (trap_to_host_vlan_ids_for_trap_to_host_pkt_info.count(pkt_info) > 0) {
2172 trap_to_host_vlan_ids_for_trap_to_host_pkt_info[pkt_info].remove(std::get<4>(pkt_info_with_vlan));
2173 } else {
2174 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",
2175 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));
2176 }
2177
2178 } else {
2179 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);
2180 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002181 } else {
2182 OPENOLT_LOG(ERROR, openolt_log_id, "acl remove error for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2183 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002184 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002185 return resp;
2186 }
2187 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002188 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002189
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002190 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002191 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002192 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002193 flowid_to_gemport.erase(key.flow_id);
2194 port_to_flows[port_no].erase(key.flow_id);
2195 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
2196 }
2197 else
2198 {
2199 flowid_to_port.erase(key.flow_id);
2200 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002201 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002202
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002203 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002204
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002205 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002206 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002207 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 -04002208 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
2209 }
2210
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002211 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002212 if (flow_id_counters != 0) {
2213 std::map<flow_pair, int>::iterator it;
2214 for(it = flow_map.begin(); it != flow_map.end(); it++) {
2215 if (it->first.first == flow_id && it->first.second == key.flow_type) {
2216 flow_id_counters -= 1;
2217 flow_map.erase(it);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002218 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002219 }
2220 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002221 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
2222
Jason Huang09b73ea2020-01-08 17:52:05 +08002223 flow_to_acl_map.erase(fl_id_fl_dir);
2224
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002225 bcmos_fastlock_unlock(&data_lock, 0);
2226
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002227 return Status::OK;
2228}
2229
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002230bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
2231 bcmos_errno err;
2232 bcmolt_tm_sched_cfg tm_sched_cfg;
2233 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2234 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
2235
Jason Huangbf45ffb2019-10-30 17:29:02 +08002236 //check TM scheduler has configured or not
2237 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2238 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002239 #ifdef TEST_MODE
2240 // It is impossible to mock the setting of tm_sched_cfg.data.state because
2241 // the actual bcmolt_cfg_get passes the address of tm_sched_cfg.hdr and we cannot
2242 // set the tm_sched_cfg.data.state. So a new stub function is created and address
2243 // of tm_sched_cfg is passed. This is one-of case where we need to add test specific
2244 // code in production code.
2245 err = bcmolt_cfg_get__tm_sched_stub(dev_id, &tm_sched_cfg);
2246 #else
Jason Huangbf45ffb2019-10-30 17:29:02 +08002247 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002248 #endif
Jason Huangbf45ffb2019-10-30 17:29:02 +08002249 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002250 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 +08002251 return err;
2252 }
2253 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
2254 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
2255 return BCM_ERR_OK;
2256 }
2257
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002258 // bcmbal_tm_sched_owner
2259 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2260
2261 /**< The output of the tm_sched object instance */
2262 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
2263
2264 if (direction.compare(upstream) == 0) {
2265 // In upstream it is NNI scheduler
2266 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
2267 } else if (direction.compare(downstream) == 0) {
2268 // In downstream it is PON scheduler
2269 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2270 }
2271
2272 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2273
2274 // bcmbal_tm_sched_type
2275 // set the deafult policy to strict priority
2276 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2277
2278 // num_priorities: Max number of strict priority scheduling elements
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002279 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, NUM_OF_PRIORITIES);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002280
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002281 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2282 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002283 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
2284 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002285 return err;
2286 }
2287
2288 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2289 direction.c_str(), tm_sched_key.id, intf_id);
2290 return BCM_ERR_OK;
2291}
2292
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002293bcmos_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 -07002294 uint32_t alloc_id, ::tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
2295 ::tech_profile::SchedulingPolicy sched_policy, ::tech_profile::TrafficShapingInfo tf_sh_info,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002296 uint32_t tech_profile_id) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002297
2298 bcmos_errno err;
2299
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002300 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002301 bcmolt_tm_sched_cfg tm_sched_cfg;
2302 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002303 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 -04002304
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002305 // bcmbal_tm_sched_owner
2306 // In downstream it is sub_term scheduler
2307 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002308
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002309 /**< The output of the tm_sched object instance */
2310 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002311
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002312 // bcmbal_tm_sched_parent
2313 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2314 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
2315 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 +00002316 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002317 be achieved using the' virtual' type of attachment.
2318 tm_sched_owner.u.sub_term.intf_id = intf_id;
2319 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2320 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002321
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002322 // bcmbal_tm_sched_type
2323 // set the deafult policy to strict priority
2324 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002325
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002326 // num_priorities: Max number of strict priority scheduling elements
2327 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002328
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002329 // bcmbal_tm_shaping
2330 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2331 uint32_t cir = tf_sh_info.cir();
2332 uint32_t pir = tf_sh_info.pir();
2333 uint32_t burst = tf_sh_info.pbs();
2334 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2335 cir, pir, burst);
2336 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2337 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2338 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2339 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2340 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2341 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002342 }
2343
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002344 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002345 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002346 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002347intf_id %d, onu_id %d, uni_id %d, port_no %u, err = %s\n", tm_sched_key.id, intf_id, onu_id, uni_id, \
2348port_no, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002349 return err;
2350 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002351 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2352uni_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 -08002353
2354 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002355 bcmolt_itupon_alloc_cfg cfg;
2356 bcmolt_itupon_alloc_key key = { };
2357 key.pon_ni = intf_id;
2358 key.alloc_id = alloc_id;
2359 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
Burak Gurdag623fada2021-04-20 22:02:36 +00002360 /*
2361 PIR: Maximum Bandwidth
2362 CIR: Assured Bandwidth
2363 GIR: Fixed Bandwidth
2364 */
Burak Gurdag03919c72020-02-04 22:46:57 +00002365 int pir_bw = tf_sh_info.pir()*125; // conversion from kbps to bytes/sec
2366 int cir_bw = tf_sh_info.cir()*125; // conversion from kbps to bytes/sec
Burak Gurdag623fada2021-04-20 22:02:36 +00002367 int gir_bw = tf_sh_info.gir()*125; // conversion from kbps to bytes/sec
2368 int guaranteed_bw = cir_bw+gir_bw;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002369 //offset to match bandwidth granularity
2370 int offset_pir_bw = pir_bw%bw_granularity;
Burak Gurdag623fada2021-04-20 22:02:36 +00002371 int offset_gir_bw = gir_bw%bw_granularity;
2372 int offset_guaranteed_bw = guaranteed_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002373
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002374 pir_bw = pir_bw - offset_pir_bw;
Burak Gurdag623fada2021-04-20 22:02:36 +00002375 gir_bw = gir_bw - offset_gir_bw;
2376 guaranteed_bw = guaranteed_bw - offset_guaranteed_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002377
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002378 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002379
Burak Gurdag623fada2021-04-20 22:02:36 +00002380 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);
2381
2382 if (pir_bw == 0) {
2383 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be at least %d bytes/sec\n",
2384 (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2385 return BCM_ERR_PARM;
2386 } else if (pir_bw < guaranteed_bw) {
2387 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed bandwidth (%d)\n",
2388 pir_bw, guaranteed_bw);
2389 return BCM_ERR_PARM;
2390 }
2391
2392 // Setting additional bw eligibility and validating bw provisionings
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002393 switch (additional_bw) {
Burak Gurdag623fada2021-04-20 22:02:36 +00002394
2395 case tech_profile::AdditionalBW::AdditionalBW_BestEffort: //AdditionalBW_BestEffort - For T-Cont types 4 & 5
2396 if (pir_bw == guaranteed_bw) {
2397 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2398bandwidth for additional bandwidth eligibility of type Best Effort\n");
2399 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002400 }
2401 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2402 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002403
2404 case tech_profile::AdditionalBW::AdditionalBW_NA: //AdditionalBW_NA - For T-Cont types 3 & 5
2405 if (guaranteed_bw == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002406 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2407additional bandwidth eligibility of type Non-Assured (NA)\n");
2408 return BCM_ERR_PARM;
Burak Gurdag623fada2021-04-20 22:02:36 +00002409 } else if (pir_bw == guaranteed_bw) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002410 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
Burak Gurdag623fada2021-04-20 22:02:36 +00002411bandwidth for additional bandwidth eligibility of type Non-Assured\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002412 return BCM_ERR_PARM;
2413 }
2414 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2415 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002416
2417 case tech_profile::AdditionalBW::AdditionalBW_None: //AdditionalBW_None - For T-Cont types 1 & 2
2418 if (guaranteed_bw != pir_bw) {
2419 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be equal to maximum bandwidth \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002420for additional bandwidth eligibility of type None\n");
2421 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002422 }
2423 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2424 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002425
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002426 default:
Burak Gurdag623fada2021-04-20 22:02:36 +00002427 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid additional bandwidth eligibility value (%d) supplied.\n", additional_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002428 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002429 }
Burak Gurdag623fada2021-04-20 22:02:36 +00002430
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002431 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2432 in a fine granularity. */
2433 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
Burak Gurdag623fada2021-04-20 22:02:36 +00002434 /* Since we can assign minimum 64000 bytes/sec for cbr_rt_bw, we prefer assigning
2435 gir_bw to cbr_nrt_bw to allow smaller amounts.
2436 TODO: Specify CBR_RT_BW and CBR_NRT_BW separately from VOLTHA */
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002437 /* Fixed Bandwidth with no critical requirement of shaping */
Burak Gurdag623fada2021-04-20 22:02:36 +00002438 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, gir_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002439 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
Burak Gurdag623fada2021-04-20 22:02:36 +00002440 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, guaranteed_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002441 /* Maximum allocated bandwidth allowed for this alloc ID */
2442 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
Burak Gurdag623fada2021-04-20 22:02:36 +00002443
2444 if (pir_bw == gir_bw) { // T-Cont Type 1 --> set alloc type to NONE
2445 // the condition cir_bw == 0 is implicitly satistied
2446 OPENOLT_LOG(INFO, openolt_log_id, "Setting alloc type to NONE since maximum bandwidth is equal to fixed bandwidth\n");
2447 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NONE);
2448 } else { // For other T-Cont types, set alloc type to NSR. TODO: read the default from a config file.
2449 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
2450 }
2451
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002452 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002453 for skipped allocations during quiet window */
2454 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2455 /**< Allocation Profile index for CBR non-RT Bandwidth */
2456 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2457 /**< Allocation Profile index for CBR RT Bandwidth */
2458 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2459 /**< Alloc ID Weight used in case of Extended DBA mode */
2460 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2461 /**< Alloc ID Priority used in case of Extended DBA mode */
2462 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2463 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002464
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002465 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002466 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002467 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 +00002468port_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 -08002469 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002470 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002471#ifndef SCALE_AND_PERF
Girish Gowdra96461052019-11-22 20:13:59 +05302472 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
2473 if (err) {
2474 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2475port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
2476 return err;
2477 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002478#endif
Girish Gowdra96461052019-11-22 20:13:59 +05302479
2480 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
2481port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
2482
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002483 }
2484
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002485 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002486}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002487
Girish Gowdra252f4972020-09-07 21:24:01 -07002488Status CreateTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002489 uint32_t intf_id = traffic_scheds->intf_id();
2490 uint32_t onu_id = traffic_scheds->onu_id();
2491 uint32_t uni_id = traffic_scheds->uni_id();
2492 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002493 std::string direction;
2494 unsigned int alloc_id;
Girish Gowdra252f4972020-09-07 21:24:01 -07002495 ::tech_profile::SchedulerConfig sched_config;
2496 ::tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002497 uint32_t priority;
2498 uint32_t weight;
Girish Gowdra252f4972020-09-07 21:24:01 -07002499 ::tech_profile::SchedulingPolicy sched_policy;
2500 ::tech_profile::TrafficShapingInfo traffic_shaping_info;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002501 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002502 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002503
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002504 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002505 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002506
2507 direction = GetDirection(traffic_sched.direction());
2508 if (direction.compare("direction-not-supported") == 0)
2509 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2510
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002511 alloc_id = traffic_sched.alloc_id();
2512 sched_config = traffic_sched.scheduler();
2513 additional_bw = sched_config.additional_bw();
2514 priority = sched_config.priority();
2515 weight = sched_config.weight();
2516 sched_policy = sched_config.sched_policy();
2517 traffic_shaping_info = traffic_sched.traffic_shaping_info();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002518 tech_profile_id = traffic_sched.tech_profile_id();
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002519 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002520 sched_policy, traffic_shaping_info, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002521 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002522 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002523 return bcm_to_grpc_err(err, "Failed to create scheduler");
2524 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002525 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002526 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002527}
Jonathan Davis70c21812018-07-19 15:32:10 -04002528
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002529bcmos_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 -04002530
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002531 bcmos_errno err;
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302532 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302533 bcmolt_status los_status;
Girish Gowdra96461052019-11-22 20:13:59 +05302534 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002535
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002536 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002537 bcmolt_itupon_alloc_cfg cfg;
2538 bcmolt_itupon_alloc_key key = { };
2539 key.pon_ni = intf_id;
2540 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302541 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002542
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002543 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002544 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2545 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002546 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2547 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002548 return err;
2549 }
Girish Gowdra96461052019-11-22 20:13:59 +05302550
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302551 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302552 if (err == BCM_ERR_OK) {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302553 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_OFF) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002554#ifndef SCALE_AND_PERF
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302555 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 +05302556 intf_id);
2557 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2558 if (err) {
2559 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2560 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
2561 return err;
2562 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002563#endif
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302564 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302565 else if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_ON) {
2566 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is enabled but LoS status is ON, not waiting for alloc cfg clear response\n",
2567 intf_id);
2568 }
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302569 else if (state == BCMOLT_INTERFACE_STATE_INACTIVE) {
2570 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is disabled, not waiting for alloc cfg clear response\n",
2571 intf_id);
2572 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302573 } else {
2574 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 +05302575 intf_id, bcmos_strerror(err));
Girish Gowdra96461052019-11-22 20:13:59 +05302576 return err;
2577 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002578 } else if (direction == downstream) {
2579 bcmolt_tm_sched_cfg cfg;
2580 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002581
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002582 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2583 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302584 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002585 } else {
2586 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2587 return BCM_ERR_OK;
2588 }
Girish Gowdra96461052019-11-22 20:13:59 +05302589
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002590 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2591 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2592 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002593 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002594intf_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 +00002595 return err;
2596 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002597 }
2598
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002599 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d, tech_profile_id %d\n",
2600 direction.c_str(), sched_id, intf_id, onu_id, tech_profile_id);
2601 free_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002602 return BCM_ERR_OK;
2603}
2604
Girish Gowdra252f4972020-09-07 21:24:01 -07002605Status RemoveTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002606 uint32_t intf_id = traffic_scheds->intf_id();
2607 uint32_t onu_id = traffic_scheds->onu_id();
2608 uint32_t uni_id = traffic_scheds->uni_id();
2609 std::string direction;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002610 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002611 bcmos_errno err;
2612
2613 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002614 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002615
2616 direction = GetDirection(traffic_sched.direction());
2617 if (direction.compare("direction-not-supported") == 0)
2618 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2619
2620 int alloc_id = traffic_sched.alloc_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002621 int tech_profile_id = traffic_sched.tech_profile_id();
2622 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002623 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002624 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002625 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2626 }
2627 }
2628 return Status::OK;
2629}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002630
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002631bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2632 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002633 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002634 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2635 bcmolt_tm_qmp_key tm_qmp_key;
2636 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002637
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002638 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2639 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002640 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed tm queue mapping profile count is 16.\n");
2641 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002642 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002643
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002644 tm_qmp_key.id = tm_qmp_id;
2645 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2646 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2647 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002648
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002649 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2650 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2651 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002652 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2653 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002654
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002655 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002656 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002657 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2658 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002659 return err;
2660 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002661
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002662 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2663 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002664 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002665}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002666
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002667bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2668 bcmos_errno err;
2669 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2670 bcmolt_tm_qmp_key tm_qmp_key;
2671 tm_qmp_key.id = tm_qmp_id;
2672
2673 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2674 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2675 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002676 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2677 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002678 return err;
2679 }
2680
2681 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2682 tm_qmp_key.id);
2683 return BCM_ERR_OK;
2684}
2685
2686bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2687 bcmos_errno err;
2688
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002689 /* Create default queues on the given PON/NNI scheduler */
2690 for (int queue_id = 0; queue_id < NUMBER_OF_DEFAULT_INTERFACE_QUEUES; queue_id++) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002691 bcmolt_tm_queue_cfg tm_queue_cfg;
2692 bcmolt_tm_queue_key tm_queue_key = {};
2693 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2694 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002695 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2696 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2697 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002698
2699 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2700 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2701 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2702
2703 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2704 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002705 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", \
2706 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 +00002707 return err;
2708 }
2709
2710 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2711 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2712 }
2713 return BCM_ERR_OK;
2714}
2715
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002716bcmos_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 +00002717 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 +00002718 bcmos_errno err;
2719 bcmolt_tm_queue_cfg cfg;
2720 bcmolt_tm_queue_key key = { };
2721 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 +00002722gemport_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 +00002723
2724 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002725 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002726
2727 if (priority > 7) {
2728 return BCM_ERR_RANGE;
2729 }
2730
2731 /* FIXME: The upstream queues have to be created once only.
2732 The upstream queues on the NNI scheduler are shared by all subscribers.
2733 When the first scheduler comes in, the queues get created, and are re-used by all others.
2734 Also, these queues should be present until the last subscriber exits the system.
2735 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2736
2737 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2738 for each GEM in TECH PROFILE */
2739 key.id = queue_id_list[priority];
2740
2741 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2742 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2743 key.id = 0;
2744 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2745 }
2746 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2747 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2748 }
2749 else {
2750 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2751 }
2752
2753 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2754
2755 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2756 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
2757
2758 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2759 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002760 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002761sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, tech_profile_id %d, err = %s\n", \
2762 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 +00002763 return err;
2764 }
2765
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302766 if (direction == upstream || direction == downstream) {
2767 Status st = install_gem_port(access_intf_id, onu_id, uni_id, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07002768 if (st.error_code() != grpc::StatusCode::ALREADY_EXISTS && st.error_code() != grpc::StatusCode::OK) {
2769 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);
2770 return BCM_ERR_INTERNAL;
2771 }
2772 }
2773
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002774 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 +00002775intf_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 +00002776 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002777}
2778
Girish Gowdra252f4972020-09-07 21:24:01 -07002779Status CreateTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002780 uint32_t intf_id = traffic_queues->intf_id();
2781 uint32_t onu_id = traffic_queues->onu_id();
2782 uint32_t uni_id = traffic_queues->uni_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002783 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002784 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002785 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002786 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002787 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 +00002788
2789 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2790 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2791 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2792 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002793 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002794
2795 direction = GetDirection(traffic_queue.direction());
2796 if (direction.compare("direction-not-supported") == 0)
2797 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2798
2799 queues_priority_q[i] = traffic_queue.priority();
2800 queues_pbit_map[i] = traffic_queue.pbit_map();
2801 }
2802
2803 std::vector<uint32_t> tmq_map_profile(8, 0);
2804 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2805 queues_priority_q, COUNT_OF(queues_priority_q));
2806 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002807 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002808
2809 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2810 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002811 err = CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2812 if (err != BCM_ERR_OK) {
2813 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2814 return bcm_to_grpc_err(err, "Failed to create tm queue mapping profile");
2815 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002816 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2817 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2818 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2819 }
2820 }
2821
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002822 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002823 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002824
2825 direction = GetDirection(traffic_queue.direction());
2826 if (direction.compare("direction-not-supported") == 0)
2827 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2828
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002829 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 +00002830
Girish Gowdruf26cf882019-05-01 23:47:58 -07002831 // If the queue exists already, lets not return failure and break the loop.
2832 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002833 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002834 return bcm_to_grpc_err(err, "Failed to create queue");
2835 }
2836 }
2837 return Status::OK;
2838}
2839
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002840bcmos_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 +00002841 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 +00002842 bcmolt_tm_queue_cfg cfg;
2843 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002844 bcmos_errno err;
2845
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302846 // Gemports are bi-directional (except in multicast case). We create the gem port when we create the
2847 // upstream/downstream queue (see CreateQueue function) and it makes sense to delete them when remove the queues.
2848 // For multicast case we do not manage the install/remove of gem port in agent application. It is managed by BAL.
2849 if (direction == upstream || direction == downstream) {
2850 Status st = remove_gem_port(access_intf_id, onu_id, uni_id, gemport_id);
2851 if (st.error_code() != grpc::StatusCode::OK) {
2852 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);
2853 return BCM_ERR_INTERNAL;
2854 }
2855 }
2856
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002857 if (direction == downstream) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002858 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2859 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 +00002860 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002861 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002862 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 -08002863 return BCM_ERR_OK;
2864 }
2865 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002866 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2867 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002868 return BCM_ERR_OK;
2869 }
2870
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002871 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2872 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2873 // Reset the queue id to 0 when using fixed queue.
2874 key.id = 0;
2875 }
2876 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2877 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2878 }
2879 else {
2880 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2881 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002882
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002883 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2884 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002885 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002886 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, queue_id %d, sched_id %d, \
2887tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n",
2888 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 -08002889 return err;
2890 }
2891
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002892 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2893intf_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 -08002894
2895 return BCM_ERR_OK;
2896}
2897
Girish Gowdra252f4972020-09-07 21:24:01 -07002898Status RemoveTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002899 uint32_t intf_id = traffic_queues->intf_id();
2900 uint32_t onu_id = traffic_queues->onu_id();
2901 uint32_t uni_id = traffic_queues->uni_id();
2902 uint32_t port_no = traffic_queues->port_no();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002903 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002904 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002905 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002906 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002907 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 +00002908
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002909 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002910 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002911
2912 direction = GetDirection(traffic_queue.direction());
2913 if (direction.compare("direction-not-supported") == 0)
2914 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2915
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002916 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 -08002917 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002918 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002919 return bcm_to_grpc_err(err, "Failed to remove queue");
2920 }
Jonathan Davis70c21812018-07-19 15:32:10 -04002921 }
2922
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002923 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 +00002924 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002925 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002926
2927 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
2928 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002929 err = RemoveTrafficQueueMappingProfile(tm_qmp_id);
2930 if (err != BCM_ERR_OK) {
2931 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2932 return bcm_to_grpc_err(err, "Failed to remove tm queue mapping profile");
2933 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002934 }
2935 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002936 clear_qos_type(intf_id, onu_id, uni_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04002937 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04002938}
Jason Huangbf45ffb2019-10-30 17:29:02 +08002939
Girish Gowdra252f4972020-09-07 21:24:01 -07002940Status PerformGroupOperation_(const ::openolt::Group *group_cfg) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002941
2942 bcmos_errno err;
2943 bcmolt_group_key key = {};
2944 bcmolt_group_cfg grp_cfg_obj;
2945 bcmolt_group_members_update grp_mem_upd;
2946 bcmolt_members_update_command grp_mem_upd_cmd;
2947 bcmolt_group_member_info member_info = {};
2948 bcmolt_group_member_info_list_u8 members = {};
2949 bcmolt_intf_ref interface_ref = {};
2950 bcmolt_egress_qos egress_qos = {};
2951 bcmolt_tm_sched_ref tm_sched_ref = {};
2952 bcmolt_action a_val = {};
2953
2954 uint32_t group_id = group_cfg->group_id();
2955
2956 OPENOLT_LOG(INFO, openolt_log_id, "PerformGroupOperation request received for Group %d\n", group_id);
2957
2958 if (group_id >= 0) {
2959 key.id = group_id;
2960 }
2961 else {
2962 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
2963 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
2964 }
2965
2966 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2967 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
2968
2969 OPENOLT_LOG(INFO, openolt_log_id, "Checking if Group %d exists...\n",group_id);
2970
2971 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
2972 if (err != BCM_ERR_OK) {
2973 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
2974 return bcm_to_grpc_err(err, "Error in querying group");
2975 }
2976
2977 members.len = group_cfg->members_size();
2978
2979 // IMPORTANT: A member cannot be added to a group if the group type is not determined.
2980 // Group type is determined after a flow is assigned to it.
2981 // Therefore, a group must be created first, then a flow (with multicast type) must be assigned to it.
2982 // Only then we can add members to the group.
2983
2984 // if group does not exist, create it and return.
2985 if (grp_cfg_obj.data.state == BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
2986
2987 if (members.len != 0) {
2988 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);
2989 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Non-empty member list given for non-existent group");
2990 } else {
2991
2992 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2993 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, cookie, key.id);
2994
2995 /* Setting group actions and action parameters, if any.
2996 Only remove_outer_tag and translate_inner_tag actions and i_vid action parameter
2997 are supported for multicast groups in BAL 3.1.
2998 */
2999 const ::openolt::Action& action = group_cfg->action();
3000 const ::openolt::ActionCmd &cmd = action.cmd();
3001
3002 bcmolt_action_cmd_id cmd_bmask = BCMOLT_ACTION_CMD_ID_NONE;
3003 if (cmd.remove_outer_tag()) {
3004 OPENOLT_LOG(INFO, openolt_log_id, "Action remove_outer_tag applied to Group %d.\n", group_id);
3005 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
3006 }
3007
3008 if (cmd.translate_inner_tag()) {
3009 OPENOLT_LOG(INFO, openolt_log_id, "Action translate_inner_tag applied to Group %d.\n", group_id);
3010 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG);
3011 }
3012
3013 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, cmd_bmask);
3014
3015 if (action.i_vid()) {
3016 OPENOLT_LOG(INFO, openolt_log_id, "Setting action parameter i_vid=%d for Group %d.\n", action.i_vid(), group_id);
3017 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
3018 }
3019
3020 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, action, a_val);
3021
3022 // Create group
3023 err = bcmolt_cfg_set(dev_id, &(grp_cfg_obj.hdr));
3024
3025 if (BCM_ERR_OK != err) {
3026 BCM_LOG(ERROR, openolt_log_id, "Failed to create Group %d, err = %s (%d)\n", key.id, bcmos_strerror(err), err);
3027 return bcm_to_grpc_err(err, "Error in creating group");
3028 }
3029
3030 BCM_LOG(INFO, openolt_log_id, "Group %d has been created and configured with empty member list.\n", key.id);
3031 return Status::OK;
3032 }
3033 }
3034
3035 // The group already exists. Continue configuring it according to the update member command.
3036
3037 OPENOLT_LOG(INFO, openolt_log_id, "Configuring existing Group %d.\n",group_id);
3038
3039 // MEMBER LIST CONSTRUCTION
3040 // Note that members.len can be 0 here. if the group already exists and the command is SET then sending
3041 // empty list to the group is a legit operation and this actually empties the member list.
3042 members.arr = (bcmolt_group_member_info*)bcmos_calloc((members.len)*sizeof(bcmolt_group_member_info));
3043
3044 if (!members.arr) {
3045 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to allocate memory for group member list.\n");
3046 return grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "Memory exhausted during member list creation");
3047 }
3048
3049 /* SET GROUP MEMBERS UPDATE COMMAND */
Girish Gowdra252f4972020-09-07 21:24:01 -07003050 ::openolt::Group::GroupMembersCommand command = group_cfg->command();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003051 switch(command) {
Girish Gowdra252f4972020-09-07 21:24:01 -07003052 case ::openolt::Group::SET_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003053 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_SET;
3054 OPENOLT_LOG(INFO, openolt_log_id, "Setting %d members for Group %d.\n", members.len, group_id);
3055 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003056 case ::openolt::Group::ADD_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003057 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_ADD;
3058 OPENOLT_LOG(INFO, openolt_log_id, "Adding %d members to Group %d.\n", members.len, group_id);
3059 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003060 case ::openolt::Group::REMOVE_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003061 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_REMOVE;
3062 OPENOLT_LOG(INFO, openolt_log_id, "Removing %d members from Group %d.\n", members.len, group_id);
3063 break;
3064 default :
3065 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid value %d for group member command.\n", command);
3066 bcmos_free(members.arr);
3067 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group member command");
3068 }
3069
3070 // SET MEMBERS LIST
3071 for (int i = 0; i < members.len; i++) {
3072
Girish Gowdra252f4972020-09-07 21:24:01 -07003073 if (command == ::openolt::Group::REMOVE_MEMBERS) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003074 OPENOLT_LOG(INFO, openolt_log_id, "Removing group member %d from group %d\n",i,key.id);
3075 } else {
3076 OPENOLT_LOG(INFO, openolt_log_id, "Adding group member %d to group %d\n",i,key.id);
3077 }
3078
Girish Gowdra252f4972020-09-07 21:24:01 -07003079 ::openolt::GroupMember *member = (::openolt::GroupMember *) &group_cfg->members()[i];
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003080
3081 // Set member interface type
Girish Gowdra252f4972020-09-07 21:24:01 -07003082 ::openolt::GroupMember::InterfaceType if_type = member->interface_type();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003083 switch(if_type){
Girish Gowdra252f4972020-09-07 21:24:01 -07003084 case ::openolt::GroupMember::PON :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003085 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_PON);
3086 OPENOLT_LOG(INFO, openolt_log_id, "Interface type PON is assigned to GroupMember %d\n",i);
3087 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003088 case ::openolt::GroupMember::EPON_1G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003089 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_1_G);
3090 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_1G is assigned to GroupMember %d\n",i);
3091 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003092 case ::openolt::GroupMember::EPON_10G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003093 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_10_G);
3094 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_10G is assigned to GroupMember %d\n",i);
3095 break;
3096 default :
3097 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid interface type value %d for GroupMember %d.\n",if_type,i);
3098 bcmos_free(members.arr);
3099 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface type for a group member");
3100 }
3101
3102 // Set member interface id
3103 if (member->interface_id() >= 0) {
3104 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_id, member->interface_id());
3105 OPENOLT_LOG(INFO, openolt_log_id, "Interface %d is assigned to GroupMember %d\n", member->interface_id(), i);
3106 } else {
3107 bcmos_free(members.arr);
3108 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface id for a group member");
3109 }
3110
3111 // Set member interface_ref
3112 BCMOLT_FIELD_SET(&member_info, group_member_info, intf, interface_ref);
3113
3114 // Set member gem_port_id. This must be a multicast gemport.
3115 if (member->gem_port_id() >= 0) {
3116 BCMOLT_FIELD_SET(&member_info, group_member_info, svc_port_id, member->gem_port_id());
3117 OPENOLT_LOG(INFO, openolt_log_id, "GEM Port %d is assigned to GroupMember %d\n", member->gem_port_id(), i);
3118 } else {
3119 bcmos_free(members.arr);
3120 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid gem port id for a group member");
3121 }
3122
3123 // Set member scheduler id and queue_id
3124 uint32_t tm_sched_id = get_default_tm_sched_id(member->interface_id(), downstream);
3125 OPENOLT_LOG(INFO, openolt_log_id, "Scheduler %d is assigned to GroupMember %d\n", tm_sched_id, i);
3126 BCMOLT_FIELD_SET(&tm_sched_ref, tm_sched_ref, id, tm_sched_id);
3127 BCMOLT_FIELD_SET(&egress_qos, egress_qos, tm_sched, tm_sched_ref);
3128
3129 // We assume that all multicast traffic destined to a PON port is using the same fixed queue.
3130 uint32_t tm_queue_id;
3131 if (member->priority() >= 0 && member->priority() < NUMBER_OF_DEFAULT_INTERFACE_QUEUES) {
3132 tm_queue_id = queue_id_list[member->priority()];
3133 OPENOLT_LOG(INFO, openolt_log_id, "Queue %d is assigned to GroupMember %d\n", tm_queue_id, i);
3134 BCMOLT_FIELD_SET(&egress_qos, egress_qos, type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
3135 BCMOLT_FIELD_SET(&egress_qos.u.fixed_queue, egress_qos_fixed_queue, queue_id, tm_queue_id);
3136 } else {
3137 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid fixed queue priority/ID %d for GroupMember %d\n", member->priority(), i);
3138 bcmos_free(members.arr);
3139 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid queue priority for a group member");
3140 }
3141
3142 BCMOLT_FIELD_SET(&member_info, group_member_info, egress_qos, egress_qos);
3143 BCMOLT_ARRAY_ELEM_SET(&(members), i, member_info);
3144 }
3145
3146 BCMOLT_OPER_INIT(&grp_mem_upd, group, members_update, key);
3147 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.members, members);
3148 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.command, grp_mem_upd_cmd);
3149
3150 err = bcmolt_oper_submit(dev_id, &(grp_mem_upd.hdr));
3151 bcmos_free(members.arr);
3152
3153 if (BCM_ERR_OK != err) {
3154 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);
3155 return bcm_to_grpc_err(err, "Failed to submit members update operation for the group");
3156 }
3157
3158 OPENOLT_LOG(INFO, openolt_log_id, "Successfully submitted members update operation for Group %d\n", key.id);
3159
3160 return Status::OK;
3161}
Burak Gurdageb4ca2e2020-06-15 07:48:26 +00003162
3163Status DeleteGroup_(uint32_t group_id) {
3164
3165 bcmos_errno err = BCM_ERR_OK;
3166 bcmolt_group_cfg grp_cfg_obj;
3167 bcmolt_group_key key = {};
3168
3169
3170 OPENOLT_LOG(INFO, openolt_log_id, "Delete request received for group %d\n", group_id);
3171
3172 if (group_id >= 0) {
3173 key.id = group_id;
3174 } else {
3175 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
3176 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
3177 }
3178
3179 /* init the BAL INIT API */
3180 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3181
3182 OPENOLT_LOG(DEBUG, openolt_log_id, "Checking if group %d exists...\n",group_id);
3183
3184 // CONFIGURE GROUP MEMBERS
3185 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
3186 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
3187
3188 if (err != BCM_ERR_OK) {
3189 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
3190 return bcm_to_grpc_err(err, "Error in querying group");
3191 }
3192
3193 if (grp_cfg_obj.data.state != BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
3194 OPENOLT_LOG(DEBUG, openolt_log_id, "Group %d exists. Will be deleted.\n",group_id);
3195 err = bcmolt_cfg_clear(dev_id, &(grp_cfg_obj.hdr));
3196 if (err != BCM_ERR_OK) {
3197 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d cannot be deleted err = %s (%d).\n", group_id, bcmos_strerror(err), err);
3198 return bcm_to_grpc_err(err, "Failed to delete group");;
3199 }
3200 } else {
3201 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d does not exist.\n", group_id);
3202 return Status(grpc::StatusCode::NOT_FOUND, "Group not found");
3203 }
3204
3205 OPENOLT_LOG(INFO, openolt_log_id, "Group %d has been deleted successfully.\n", group_id);
3206 return Status::OK;
Jason Huang1d9cfce2020-05-20 22:58:47 +08003207}
3208
Girish Gowdra252f4972020-09-07 21:24:01 -07003209Status GetLogicalOnuDistanceZero_(uint32_t intf_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003210 bcmos_errno err = BCM_ERR_OK;
3211 uint32_t mld = 0;
3212 double LD0;
3213
3214 err = getOnuMaxLogicalDistance(intf_id, &mld);
3215 if (err != BCM_ERR_OK) {
3216 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3217 }
3218
3219 LD0 = LOGICAL_DISTANCE(mld*1000, MINIMUM_ONU_RESPONSE_RANGING_TIME, ONU_BIT_TRANSMISSION_DELAY);
3220 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance zero is %f, (PON %d)\n", LD0, intf_id);
3221 response->set_intf_id(intf_id);
3222 response->set_logical_onu_distance_zero(LD0);
3223
3224 return Status::OK;
3225}
3226
Girish Gowdra252f4972020-09-07 21:24:01 -07003227Status GetLogicalOnuDistance_(uint32_t intf_id, uint32_t onu_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003228 bcmos_errno err = BCM_ERR_OK;
3229 bcmolt_itu_onu_params itu = {};
3230 bcmolt_onu_cfg onu_cfg;
3231 bcmolt_onu_key onu_key = {};
3232 uint32_t mld = 0;
3233 double LDi;
3234
3235 onu_key.pon_ni = intf_id;
3236 onu_key.onu_id = onu_id;
3237
3238 err = getOnuMaxLogicalDistance(intf_id, &mld);
3239 if (err != BCM_ERR_OK) {
3240 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3241 }
3242
3243 /* Initialize the API struct. */
3244 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
3245 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
3246 BCMOLT_FIELD_SET_PRESENT(&itu, itu_onu_params, ranging_time);
3247 BCMOLT_FIELD_SET(&onu_cfg.data, onu_cfg_data, itu, itu);
3248 #ifdef TEST_MODE
3249 // It is impossible to mock the setting of onu_cfg.data.onu_state because
3250 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
3251 // set the onu_cfg.data.onu_state. So a new stub function is created and address
3252 // of onu_cfg is passed. This is one-of case where we need to add test specific
3253 // code in production code.
3254 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
3255 #else
3256 /* Call API function. */
3257 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
3258 #endif
3259 if (err != BCM_ERR_OK) {
3260 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);
3261 return bcm_to_grpc_err(err, "Failed to retrieve ONU ranging time");
3262 }
3263
3264 if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_ACTIVE) {
3265 OPENOLT_LOG(ERROR, openolt_log_id, "ONU is not yet activated (PON %d, ONU id %d)\n", intf_id, onu_id);
3266 return bcm_to_grpc_err(BCM_ERR_PARM, "ONU is not yet activated\n");
3267 }
3268
3269 LDi = LOGICAL_DISTANCE(mld*1000, onu_cfg.data.itu.ranging_time, ONU_BIT_TRANSMISSION_DELAY);
3270 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance is %f, (PON %d, ONU id %d)\n", LDi, intf_id, onu_id);
3271 response->set_intf_id(intf_id);
3272 response->set_onu_id(onu_id);
3273 response->set_logical_onu_distance(LDi);
3274
3275 return Status::OK;
3276}
Burak Gurdag74e3ab82020-12-17 13:35:06 +00003277
3278Status GetOnuStatistics_(uint32_t intf_id, uint32_t onu_id, openolt::OnuStatistics* onu_stats) {
3279 bcmos_errno err;
3280
3281 err = get_onu_statistics((bcmolt_interface_id)intf_id, (bcmolt_onu_id)onu_id, onu_stats);
3282
3283 if (err != BCM_ERR_OK) {
3284 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));
3285 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of ONU statistics failed");
3286 }
3287
3288 OPENOLT_LOG(INFO, openolt_log_id, "retrieved ONU statistics for PON ID = %d, ONU ID = %d\n", (int)intf_id, (int)onu_id);
3289 return Status::OK;
3290}
3291
3292Status GetGemPortStatistics_(uint32_t intf_id, uint32_t gemport_id, openolt::GemPortStatistics* gemport_stats) {
3293 bcmos_errno err;
3294
3295 err = get_gemport_statistics((bcmolt_interface_id)intf_id, (bcmolt_gem_port_id)gemport_id, gemport_stats);
3296
3297 if (err != BCM_ERR_OK) {
3298 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));
3299 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of GEMPORT statistics failed");
3300 }
3301
3302 OPENOLT_LOG(INFO, openolt_log_id, "retrieved GEMPORT statistics for PON ID = %d, GEMPORT ID = %d\n", (int)intf_id, (int)gemport_id);
3303 return Status::OK;
3304}
Orhan Kupusogluec57af02021-05-12 12:38:17 +00003305
3306Status GetPonRxPower_(uint32_t intf_id, uint32_t onu_id, openolt::PonRxPowerData* response) {
3307 bcmos_errno err = BCM_ERR_OK;
3308
3309 // check the PON intf id
3310 if (intf_id >= MAX_SUPPORTED_PON) {
3311 err = BCM_ERR_PARM;
3312 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pon intf_id - intf_id: %d, onu_id: %d\n",
3313 intf_id, onu_id);
3314 return bcm_to_grpc_err(err, "invalid pon intf_id");
3315 }
3316
3317 bcmolt_onu_rssi_measurement onu_oper; /* declare main API struct */
3318 bcmolt_onu_key onu_key; /**< Object key. */
3319 onu_rssi_compltd_key key(intf_id, onu_id);
3320 Queue<onu_rssi_complete_result> queue;
3321
3322 OPENOLT_LOG(INFO, openolt_log_id, "GetPonRxPower - intf_id %d, onu_id %d\n", intf_id, onu_id);
3323
3324 onu_key.onu_id = onu_id;
3325 onu_key.pon_ni = intf_id;
3326 /* Initialize the API struct. */
3327 BCMOLT_OPER_INIT(&onu_oper, onu, rssi_measurement, onu_key);
3328 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
3329 if (err == BCM_ERR_OK) {
3330 // initialize map
3331 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3332 onu_rssi_compltd_map.insert({key, &queue});
3333 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3334 } else {
3335 OPENOLT_LOG(ERROR, openolt_log_id, "failed to measure rssi rx power - intf_id: %d, onu_id: %d, err = %s (%d): %s\n",
3336 intf_id, onu_id, bcmos_strerror(err), err, onu_oper.hdr.hdr.err_text);
3337 return bcm_to_grpc_err(err, "failed to measure rssi rx power");
3338 }
3339
3340 onu_rssi_complete_result completed{};
3341 if (!queue.pop(completed, ONU_RSSI_COMPLETE_WAIT_TIMEOUT)) {
3342 // invalidate the queue pointer
3343 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3344 onu_rssi_compltd_map[key] = NULL;
3345 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3346 err = BCM_ERR_TIMEOUT;
3347 OPENOLT_LOG(ERROR, openolt_log_id, "timeout waiting for RSSI Measurement Completed indication intf_id %d, onu_id %d\n",
3348 intf_id, onu_id);
3349 } else {
3350 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",
3351 completed.pon_intf_id, completed.onu_id, completed.status.c_str(), completed.reason, completed.rx_power_mean_dbm);
3352
3353 response->set_intf_id(completed.pon_intf_id);
3354 response->set_onu_id(completed.onu_id);
3355 response->set_status(completed.status);
3356 response->set_fail_reason(static_cast<::openolt::PonRxPowerData_RssiMeasurementFailReason>(completed.reason));
3357 response->set_rx_power_mean_dbm(completed.rx_power_mean_dbm);
3358 }
3359
3360 // Remove entry from map
3361 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3362 onu_rssi_compltd_map.erase(key);
3363 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3364
3365 if (err == BCM_ERR_OK) {
3366 return Status::OK;
3367 } else {
3368 return bcm_to_grpc_err(err, "timeout waiting for pon rssi measurement complete indication");
3369 }
3370}