blob: 6319faae3056fe52cad6fcbbf3ba307b6fd71ef8 [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, \
68 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,
Burak Gurdag2f2618c2020-04-23 13:20:30 +000070 tech_profile::TrafficShapingInfo traffic_shaping_info, uint32_t tech_profile_id);
71static bcmos_errno RemoveSched(int intf_id, int onu_id, int uni_id, int alloc_id, std::string direction, int tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080072static bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +000073 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id, uint32_t tech_profile_id);
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -050074static bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +000075 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id, uint32_t tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000076static bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction);
77static bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction);
78
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000079inline const char *get_flow_acton_command(uint32_t command) {
80 char actions[200] = { };
81 char *s_actions_ptr = actions;
82 if (command & BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG) strcat(s_actions_ptr, "ADD_OUTER_TAG|");
83 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG) strcat(s_actions_ptr, "REMOVE_OUTER_TAG|");
84 if (command & BCMOLT_ACTION_CMD_ID_XLATE_OUTER_TAG) strcat(s_actions_ptr, "TRANSLATE_OUTER_TAG|");
85 if (command & BCMOLT_ACTION_CMD_ID_ADD_INNER_TAG) strcat(s_actions_ptr, "ADD_INNTER_TAG|");
86 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_INNER_TAG) strcat(s_actions_ptr, "REMOVE_INNER_TAG|");
87 if (command & BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG) strcat(s_actions_ptr, "TRANSLATE_INNER_TAG|");
88 if (command & BCMOLT_ACTION_CMD_ID_REMARK_OUTER_PBITS) strcat(s_actions_ptr, "REMOVE_OUTER_PBITS|");
89 if (command & BCMOLT_ACTION_CMD_ID_REMARK_INNER_PBITS) strcat(s_actions_ptr, "REMAKE_INNER_PBITS|");
90 return s_actions_ptr;
91}
92
Nicolas Palpacuerdff96792018-09-06 14:59:32 -040093Status GetDeviceInfo_(openolt::DeviceInfo* device_info) {
Craig Lutgen88a22ad2018-10-04 12:30:46 -050094 device_info->set_vendor(VENDOR_ID);
95 device_info->set_model(MODEL_ID);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -040096 device_info->set_hardware_version("");
97 device_info->set_firmware_version(firmware_version);
Craig Lutgenb2601f02018-10-23 13:04:31 -050098 device_info->set_technology(board_technology);
Craig Lutgen88a22ad2018-10-04 12:30:46 -050099 device_info->set_pon_ports(num_of_pon_ports);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500100
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800101 char serial_number[OPENOLT_FIELD_LEN];
102 memset(serial_number, '\0', OPENOLT_FIELD_LEN);
103 openolt_read_sysinfo("Serial Number", serial_number);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000104 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device serial number %s\n", serial_number);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800105 device_info->set_device_serial_number(serial_number);
106
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700107 char device_id[OPENOLT_FIELD_LEN];
108 memset(device_id, '\0', OPENOLT_FIELD_LEN);
109 openolt_read_sysinfo("MAC", device_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000110 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device mac address %s\n", device_id);
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700111 device_info->set_device_id(device_id);
112
Craig Lutgenb2601f02018-10-23 13:04:31 -0500113 // Legacy, device-wide ranges. To be deprecated when adapter
114 // is upgraded to support per-interface ranges
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000115 if (board_technology == "XGS-PON") {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500116 device_info->set_onu_id_start(1);
117 device_info->set_onu_id_end(255);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600118 device_info->set_alloc_id_start(MIN_ALLOC_ID_XGSPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500119 device_info->set_alloc_id_end(16383);
120 device_info->set_gemport_id_start(1024);
121 device_info->set_gemport_id_end(65535);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500122 device_info->set_flow_id_start(1);
123 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500124 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000125 else if (board_technology == "GPON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500126 device_info->set_onu_id_start(1);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500127 device_info->set_onu_id_end(127);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600128 device_info->set_alloc_id_start(MIN_ALLOC_ID_GPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500129 device_info->set_alloc_id_end(767);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500130 device_info->set_gemport_id_start(256);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500131 device_info->set_gemport_id_end(4095);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500132 device_info->set_flow_id_start(1);
133 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500134 }
Craig Lutgenb2601f02018-10-23 13:04:31 -0500135
136 std::map<std::string, openolt::DeviceInfo::DeviceResourceRanges*> ranges;
137 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
138 std::string intf_technology = intf_technologies[intf_id];
139 openolt::DeviceInfo::DeviceResourceRanges *range = ranges[intf_technology];
140 if(range == nullptr) {
141 range = device_info->add_ranges();
142 ranges[intf_technology] = range;
143 range->set_technology(intf_technology);
144
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000145 if (intf_technology == "XGS-PON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500146 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
147
148 pool = range->add_pools();
149 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
150 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
151 pool->set_start(1);
152 pool->set_end(255);
153
154 pool = range->add_pools();
155 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
Girish Gowdra1d018a52020-03-05 14:38:20 -0800156 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500157 pool->set_start(1024);
158 pool->set_end(16383);
159
160 pool = range->add_pools();
161 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
Girish Gowdra1d018a52020-03-05 14:38:20 -0800162 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500163 pool->set_start(1024);
164 pool->set_end(65535);
165
166 pool = range->add_pools();
167 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
168 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
169 pool->set_start(1);
170 pool->set_end(16383);
171 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000172 else if (intf_technology == "GPON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500173 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
174
175 pool = range->add_pools();
176 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
177 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
178 pool->set_start(1);
179 pool->set_end(127);
180
181 pool = range->add_pools();
182 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
Girish Gowdra1d018a52020-03-05 14:38:20 -0800183 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500184 pool->set_start(256);
185 pool->set_end(757);
186
187 pool = range->add_pools();
188 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
Girish Gowdra1d018a52020-03-05 14:38:20 -0800189 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500190 pool->set_start(256);
191 pool->set_end(4095);
192
193 pool = range->add_pools();
194 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
195 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
196 pool->set_start(1);
197 pool->set_end(16383);
198 }
199 }
200
201 range->add_intf_ids(intf_id);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500202 }
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400203
204 // FIXME: Once dependency problem is fixed
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500205 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400206 // device_info->set_onu_id_end(XGPON_NUM_OF_ONUS - 1);
207 // device_info->set_alloc_id_start(1024);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500208 // device_info->set_alloc_id_end(XGPON_NUM_OF_ALLOC_IDS * num_of_pon_ports ? - 1);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400209 // device_info->set_gemport_id_start(XGPON_MIN_BASE_SERVICE_PORT_ID);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500210 // device_info->set_gemport_id_end(XGPON_NUM_OF_GEM_PORT_IDS_PER_PON * num_of_pon_ports ? - 1);
211 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400212
213 return Status::OK;
214}
215
Shad Ansari627b5782018-08-13 22:49:32 +0000216Status Enable_(int argc, char *argv[]) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000217 bcmos_errno err;
218 bcmolt_host_init_parms init_parms = {};
219 init_parms.transport.type = BCM_HOST_API_CONN_LOCAL;
220 unsigned int failed_enable_device_cnt = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000221
Shad Ansariedef2132018-08-10 22:14:50 +0000222 if (!state.is_activated()) {
Shad Ansari627b5782018-08-13 22:49:32 +0000223
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500224 vendor_init();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000225 /* Initialize host subsystem */
226 err = bcmolt_host_init(&init_parms);
227 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500228 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to init OLT, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000229 return bcm_to_grpc_err(err, "Failed to init OLT");
230 }
231
232 bcmcli_session_parm mon_session_parm;
233 /* Create CLI session */
234 memset(&mon_session_parm, 0, sizeof(mon_session_parm));
235 mon_session_parm.get_prompt = openolt_cli_get_prompt_cb;
236 mon_session_parm.access_right = BCMCLI_ACCESS_ADMIN;
237 bcmos_errno rc = bcmcli_session_open(&mon_session_parm, &current_session);
238 BUG_ON(rc != BCM_ERR_OK);
239
240 /* API CLI */
241 bcm_openolt_api_cli_init(NULL, current_session);
242
243 /* Add quit command */
244 BCMCLI_MAKE_CMD_NOPARM(NULL, "quit", "Quit", bcm_cli_quit);
245
246 err = bcmolt_apiend_cli_init();
247 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500248 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to add apiend init, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000249 return bcm_to_grpc_err(err, "Failed to add apiend init");
250 }
251
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800252 bcmos_fastlock_init(&data_lock, 0);
Girish Gowdra96461052019-11-22 20:13:59 +0530253 bcmos_fastlock_init(&alloc_cfg_wait_lock, 0);
Girish Gowdra7a79dae2020-02-10 18:22:11 +0530254 bcmos_fastlock_init(&onu_deactivate_wait_lock, 0);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000255 OPENOLT_LOG(INFO, openolt_log_id, "Enable OLT - %s-%s\n", VENDOR_ID, MODEL_ID);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600256
Jason Huangbf45ffb2019-10-30 17:29:02 +0800257 //check BCM daemon is connected or not
258 Status status = check_connection();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000259 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800260 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000261 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800262 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000263 Status status = SubscribeIndication();
264 if (!status.ok()) {
265 OPENOLT_LOG(ERROR, openolt_log_id, "SubscribeIndication failed - %s : %s\n",
266 grpc_status_code_to_string(status.error_code()).c_str(),
267 status.error_message().c_str());
268 return status;
269 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800270
271 //check BAL state in initial stage
272 status = check_bal_ready();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000273 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800274 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000275 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800276 }
277
278 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000279 bcmos_errno err;
280 bcmolt_odid dev;
281 OPENOLT_LOG(INFO, openolt_log_id, "Enabling PON %d Devices ... \n", BCM_MAX_DEVS_PER_LINE_CARD);
282 for (dev = 0; dev < BCM_MAX_DEVS_PER_LINE_CARD; dev++) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400283 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000284 bcmolt_device_key dev_key = { };
285 dev_key.device_id = dev;
286 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
287 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
288 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
Jason Huangbf45ffb2019-10-30 17:29:02 +0800289 if (err == BCM_ERR_NOT_CONNECTED) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000290 bcmolt_device_key key = {.device_id = dev};
291 bcmolt_device_connect oper;
292 BCMOLT_OPER_INIT(&oper, device, connect, key);
293 if (MODEL_ID == "asfvolt16") {
294 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
295 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_XGS__2_X);
296 } else if (MODEL_ID == "asgvolt64") {
297 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
298 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
299 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
300 }
301 err = bcmolt_oper_submit(dev_id, &oper.hdr);
302 if (err) {
303 failed_enable_device_cnt ++;
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500304 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 +0000305 if (failed_enable_device_cnt == BCM_MAX_DEVS_PER_LINE_CARD) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500306 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 +0000307 return Status(grpc::StatusCode::INTERNAL, "Failed to activate all PON ports");
308 }
309 }
310 bcmos_usleep(200000);
311 }
312 else {
313 OPENOLT_LOG(WARNING, openolt_log_id, "PON deivce %d already connected\n", dev);
314 state.activate();
315 }
316 }
317 init_stats();
Shad Ansari627b5782018-08-13 22:49:32 +0000318 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000319 }
Shad Ansariedef2132018-08-10 22:14:50 +0000320
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000321 /* Start CLI */
322 OPENOLT_LOG(INFO, def_log_id, "Starting CLI\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400323 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000324 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400325}
326
327Status Disable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400328 //In the earlier implementation Disabling olt is done by disabling the NNI port associated with that.
329 //In inband scenario instead of using management interface to establish connection with adapter ,NNI interface will be used.
330 //Disabling NNI port on olt disable causes connection loss between adapter and agent.
331 //To overcome this disable is implemented by disabling all the PON ports
332 //associated with the device so as to support both in-band
333 //and out of band scenarios.
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400334
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400335 Status status;
336 int failedCount = 0;
337 for (int i = 0; i < NumPonIf_(); i++) {
338 status = DisablePonIf_(i);
339 if (!status.ok()) {
340 failedCount+=1;
341 BCM_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", i);
342 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400343 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400344 if (failedCount == 0) {
345 state.deactivate();
346 openolt::Indication ind;
347 openolt::OltIndication* olt_ind = new openolt::OltIndication;
348 olt_ind->set_oper_state("down");
349 ind.set_allocated_olt_ind(olt_ind);
350 BCM_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
351 oltIndQ.push(ind);
352 return Status::OK;
353 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000354 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400355 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to disable olt ,all the PON ports are still in enabled state");
356 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400357
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400358 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 -0400359}
360
361Status Reenable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400362 Status status;
363 int failedCount = 0;
364 for (int i = 0; i < NumPonIf_(); i++) {
365 status = EnablePonIf_(i);
366 if (!status.ok()) {
367 failedCount+=1;
368 BCM_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", i);
369 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400370 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000371 if (failedCount == 0) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400372 state.activate();
373 openolt::Indication ind;
374 openolt::OltIndication* olt_ind = new openolt::OltIndication;
375 olt_ind->set_oper_state("up");
376 ind.set_allocated_olt_ind(olt_ind);
377 BCM_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
378 oltIndQ.push(ind);
379 return Status::OK;
380 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000381 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400382 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to re-enable olt ,all the PON ports are still in disabled state");
383 }
384 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 +0000385}
386
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000387inline uint64_t get_flow_status(uint16_t flow_id, uint16_t flow_type, uint16_t data_id) {
388 bcmos_errno err;
389 bcmolt_flow_key flow_key;
390 bcmolt_flow_cfg flow_cfg;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400391
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000392 flow_key.flow_id = flow_id;
393 flow_key.flow_type = (bcmolt_flow_type)flow_type;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400394
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000395 BCMOLT_CFG_INIT(&flow_cfg, flow, flow_key);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400396
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000397 switch (data_id) {
398 case ONU_ID: //onu_id
399 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, onu_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500400 #ifdef TEST_MODE
401 // It is impossible to mock the setting of flow_cfg.data.state because
402 // the actual bcmolt_cfg_get passes the address of flow_cfg.hdr and we cannot
403 // set the flow_cfg.data. So a new stub function is created and address
404 // of flow_cfg is passed. This is one-of case where we need to add test specific
405 // code in production code.
406 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
407 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000408 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500409 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000410 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500411 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get onu_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000412 return err;
413 }
414 return flow_cfg.data.onu_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400415 case FLOW_TYPE:
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500416 #ifdef TEST_MODE
417 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
418 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000419 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500420 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000421 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500422 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get flow_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000423 return err;
424 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400425 return flow_cfg.key.flow_type;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000426 case SVC_PORT_ID: //svc_port_id
427 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, svc_port_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500428 #ifdef TEST_MODE
429 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
430 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000431 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500432 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000433 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500434 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 +0000435 return err;
436 }
437 return flow_cfg.data.svc_port_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400438 case PRIORITY:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000439 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, priority);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500440 #ifdef TEST_MODE
441 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
442 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000443 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500444 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000445 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500446 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get priority, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000447 return err;
448 }
449 return flow_cfg.data.priority;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400450 case COOKIE: //cookie
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000451 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, cookie);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500452 #ifdef TEST_MODE
453 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
454 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000455 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500456 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000457 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500458 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get cookie, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000459 return err;
460 }
461 return flow_cfg.data.cookie;
462 case INGRESS_INTF_TYPE: //ingress intf_type
463 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500464 #ifdef TEST_MODE
465 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
466 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000467 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500468 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000469 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500470 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 +0000471 return err;
472 }
473 return flow_cfg.data.ingress_intf.intf_type;
474 case EGRESS_INTF_TYPE: //egress intf_type
475 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500476 #ifdef TEST_MODE
477 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
478 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000479 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500480 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000481 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500482 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 +0000483 return err;
484 }
485 return flow_cfg.data.egress_intf.intf_type;
486 case INGRESS_INTF_ID: //ingress intf_id
487 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500488 #ifdef TEST_MODE
489 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
490 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000491 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500492 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000493 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500494 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 +0000495 return err;
496 }
497 return flow_cfg.data.ingress_intf.intf_id;
498 case EGRESS_INTF_ID: //egress intf_id
499 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500500 #ifdef TEST_MODE
501 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
502 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000503 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500504 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000505 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500506 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 +0000507 return err;
508 }
509 return flow_cfg.data.egress_intf.intf_id;
510 case CLASSIFIER_O_VID:
511 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500512 #ifdef TEST_MODE
513 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
514 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000515 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500516 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000517 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500518 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 +0000519 return err;
520 }
521 return flow_cfg.data.classifier.o_vid;
522 case CLASSIFIER_O_PBITS:
523 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500524 #ifdef TEST_MODE
525 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
526 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000527 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500528 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000529 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500530 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 +0000531 return err;
532 }
533 return flow_cfg.data.classifier.o_pbits;
534 case CLASSIFIER_I_VID:
535 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500536 #ifdef TEST_MODE
537 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
538 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000539 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500540 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000541 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500542 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 +0000543 return err;
544 }
545 return flow_cfg.data.classifier.i_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400546 case CLASSIFIER_I_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000547 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500548 #ifdef TEST_MODE
549 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
550 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000551 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500552 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000553 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500554 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier i_pbits, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000555 return err;
556 }
557 return flow_cfg.data.classifier.i_pbits;
558 case CLASSIFIER_ETHER_TYPE:
559 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500560 #ifdef TEST_MODE
561 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
562 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000563 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500564 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000565 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500566 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier ether_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000567 return err;
568 }
569 return flow_cfg.data.classifier.ether_type;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400570 case CLASSIFIER_IP_PROTO:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000571 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500572 #ifdef TEST_MODE
573 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
574 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000575 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500576 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000577 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500578 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier ip_proto, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000579 return err;
580 }
581 return flow_cfg.data.classifier.ip_proto;
582 case CLASSIFIER_SRC_PORT:
583 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500584 #ifdef TEST_MODE
585 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
586 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000587 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500588 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000589 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500590 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier src_port, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000591 return err;
592 }
593 return flow_cfg.data.classifier.src_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400594 case CLASSIFIER_DST_PORT:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000595 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500596 #ifdef TEST_MODE
597 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
598 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000599 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500600 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000601 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500602 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier dst_port, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000603 return err;
604 }
605 return flow_cfg.data.classifier.dst_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400606 case CLASSIFIER_PKT_TAG_TYPE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000607 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500608 #ifdef TEST_MODE
609 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
610 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000611 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500612 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000613 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500614 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier pkt_tag_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000615 return err;
616 }
617 return flow_cfg.data.classifier.pkt_tag_type;
618 case EGRESS_QOS_TYPE:
619 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500620 #ifdef TEST_MODE
621 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
622 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000623 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500624 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000625 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500626 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000627 return err;
628 }
629 return flow_cfg.data.egress_qos.type;
630 case EGRESS_QOS_QUEUE_ID:
631 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500632 #ifdef TEST_MODE
633 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
634 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000635 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500636 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000637 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500638 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos queue_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000639 return err;
640 }
641 switch (flow_cfg.data.egress_qos.type) {
642 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE:
643 return flow_cfg.data.egress_qos.u.fixed_queue.queue_id;
644 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE:
645 return flow_cfg.data.egress_qos.u.tc_to_queue.tc_to_queue_id;
646 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC:
647 return flow_cfg.data.egress_qos.u.pbit_to_tc.tc_to_queue_id;
648 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE:
649 return flow_cfg.data.egress_qos.u.priority_to_queue.tm_q_set_id;
650 case BCMOLT_EGRESS_QOS_TYPE_NONE:
651 default:
652 return -1;
653 }
654 case EGRESS_QOS_TM_SCHED_ID:
655 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500656 #ifdef TEST_MODE
657 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
658 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000659 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500660 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000661 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500662 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos tm_sched_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000663 return err;
664 }
665 return flow_cfg.data.egress_qos.tm_sched.id;
666 case ACTION_CMDS_BITMASK:
667 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500668 #ifdef TEST_MODE
669 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
670 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000671 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500672 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000673 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500674 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action cmds_bitmask, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000675 return err;
676 }
677 return flow_cfg.data.action.cmds_bitmask;
678 case ACTION_O_VID:
679 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500680 #ifdef TEST_MODE
681 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
682 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000683 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500684 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000685 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500686 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action o_vid, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000687 return err;
688 }
689 return flow_cfg.data.action.o_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400690 case ACTION_O_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000691 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500692 #ifdef TEST_MODE
693 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
694 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000695 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500696 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000697 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500698 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action o_pbits, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000699 return err;
700 }
701 return flow_cfg.data.action.o_pbits;
702 case ACTION_I_VID:
703 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500704 #ifdef TEST_MODE
705 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
706 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000707 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500708 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000709 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500710 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action i_vid, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000711 return err;
712 }
713 return flow_cfg.data.action.i_vid;
714 case ACTION_I_PBITS:
715 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500716 #ifdef TEST_MODE
717 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
718 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000719 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500720 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000721 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500722 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action i_pbits, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000723 return err;
724 }
725 return flow_cfg.data.action.i_pbits;
726 case STATE:
727 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, state);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500728 #ifdef TEST_MODE
729 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
730 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000731 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500732 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000733 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500734 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get state, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000735 return err;
736 }
737 return flow_cfg.data.state;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000738 case GROUP_ID:
739 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, group_id);
740 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
741 if (err) {
742 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get group_id, err = %s\n",bcmos_strerror(err));
743 return err;
744 }
745 return flow_cfg.data.group_id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000746 default:
747 return BCM_ERR_INTERNAL;
748 }
749
750 return err;
751}
752
753Status EnablePonIf_(uint32_t intf_id) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400754 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000755 bcmolt_pon_interface_cfg interface_obj;
756 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
757 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
758 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530759 bcmolt_status los_status;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000760
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530761 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000762 if (err == BCM_ERR_OK) {
763 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800764 OPENOLT_LOG(WARNING, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000765 return Status::OK;
766 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400767 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000768 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
769 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
770 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
771 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.interval, 5000);
772 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.onu_post_discovery_mode,
Girish Gowdra24297032020-03-23 12:32:37 -0700773 BCMOLT_ONU_POST_DISCOVERY_MODE_NONE);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000774 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.los, true);
775 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.onu_alarms, true);
776 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.tiwi, true);
777 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.ack_timeout, true);
778 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.sfi, true);
779 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.loki, true);
780 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
781 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
782
783 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
784 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500785 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 +0000786 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
787 }
788 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
789 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500790 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 +0000791 return bcm_to_grpc_err(err, "Failed to enable PON interface");
792 }
793 else {
794 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
795 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
796 CreateDefaultSched(intf_id, downstream);
797 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400798 }
799
800 return Status::OK;
801}
802
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500803Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000804 bcmos_errno err;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400805 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000806 bcmolt_device_key dev_key = { };
807 bcmolt_olt_cfg olt_cfg = { };
808 bcmolt_olt_key olt_key = { };
809 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
810 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500811
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000812 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
813 topo.topology_maps.arr = &topo_map[0];
814 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
815 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
816 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400817 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000818 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400819 #ifdef TEST_MODE
820 // It is impossible to mock the setting of olt_cfg.data.bal_state because
821 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
822 // set the olt_cfg.data.topology. So a new stub function is created and address
823 // of olt_cfg is passed. This is one-of case where we need to test add specific
824 // code in production code.
825 err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
826 #else
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000827 err = bcmolt_cfg_get_mult_retry(dev_id, &olt_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400828 #endif
829 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500830 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 +0000831 return bcm_to_grpc_err(err, "cfg: Failed to query OLT topology");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500832 }
833
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000834 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
835 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500836
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400837 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
838 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000839 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500840
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000841 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
842 num_of_nni_ports,
843 num_of_pon_ports,
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400844 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500845
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000846 uint32_t num_failed_cfg_gets = 0;
Jason Huang09b73ea2020-01-08 17:52:05 +0800847 static std::string openolt_version = firmware_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000848 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
849 dev_key.device_id = devid;
850 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
851 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
852 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
853 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000854 err = bcmolt_cfg_get_mult_retry(dev_id, &dev_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400855 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500856 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 +0000857 num_failed_cfg_gets++;
858 continue;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000859 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500860
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000861 std::string bal_version;
862 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
863 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
864 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
Jason Huang09b73ea2020-01-08 17:52:05 +0800865 firmware_version = "BAL." + bal_version + "__" + openolt_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000866
867 switch(dev_cfg.data.system_mode) {
868 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
869 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
870 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
871 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
872 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
873 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
874 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
875 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
876 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
877 case 20: board_technology = MIXED_TECH; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,MIXED_TECH); break;
878 }
879
880 switch(dev_cfg.data.chip_family) {
Jason Huang09b73ea2020-01-08 17:52:05 +0800881 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X: chip_family = "Maple"; break;
882 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X: chip_family = "Aspen"; break;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000883 }
884
Jason Huang09b73ea2020-01-08 17:52:05 +0800885 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s, family: %s, board_technology: %s\n",
886 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 +0000887
888 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500889 }
890
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000891 /* 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 +0000892 only the devices that retured success*/
893 if (num_failed_cfg_gets == BCM_MAX_DEVS_PER_LINE_CARD) {
894 OPENOLT_LOG(ERROR, openolt_log_id, "device: Query of all the devices failed\n");
895 return bcm_to_grpc_err(err, "device: All devices failed query");
896 }
897
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500898 return Status::OK;
899}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400900
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000901Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000902 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000903 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
904 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
905 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -0500906
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400907 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000908 if (err == BCM_ERR_OK) {
909 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800910 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000911 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
912 CreateDefaultSched(intf_id, upstream);
913 CreateDefaultQueue(intf_id, upstream);
914 return Status::OK;
915 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
916 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
917 return Status::OK;
918 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -0500919 }
920
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000921 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
922 if (set_state) {
923 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
924 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
925 } else {
926 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
927 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
928 }
929 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
930 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500931 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err = %s\n",
932 (set_state)?"enable":"disable", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000933 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
934 }
935 else {
936 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
937 if (set_state) {
938 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
939 CreateDefaultSched(intf_id, upstream);
940 CreateDefaultQueue(intf_id, upstream);
941 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400942 }
943
944 return Status::OK;
945}
946
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -0400947Status DisablePonIf_(uint32_t intf_id) {
Chaitrashree G S73e084d2019-11-20 16:18:59 -0500948 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000949 bcmolt_pon_interface_cfg interface_obj;
Chaitrashree G S73e084d2019-11-20 16:18:59 -0500950 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
951 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -0400952
Chaitrashree G S73e084d2019-11-20 16:18:59 -0500953 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
954 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
955 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_DISABLE);
956
957 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
958 if (err != BCM_ERR_OK) {
959 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable discovery of onu, PON interface %d, err %d\n", intf_id, err);
960 return bcm_to_grpc_err(err, "Failed to disable discovery of onu");
961 }
962
963 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
964 operation, BCMOLT_INTERFACE_OPERATION_INACTIVE);
965
966 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
967 if (err != BCM_ERR_OK) {
968 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 -0400969 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -0400970 }
971
Chaitrashree G S73e084d2019-11-20 16:18:59 -0500972 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled PON interface: %d\n", intf_id);
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -0400973 return Status::OK;
974}
975
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000976Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700977 const char *vendor_id, const char *vendor_specific, uint32_t pir) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000978 bcmos_errno err = BCM_ERR_OK;
979 bcmolt_onu_cfg onu_cfg;
980 bcmolt_onu_key onu_key;
981 bcmolt_serial_number serial_number; /**< ONU serial number */
982 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000983
Girish Gowdra24297032020-03-23 12:32:37 -0700984 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
985 bcmolt_onu_state onu_state;
986
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000987 onu_key.onu_id = onu_id;
988 onu_key.pon_ni = intf_id;
989 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
990 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Girish Gowdra24297032020-03-23 12:32:37 -0700991#ifdef TEST_MODE
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -0500992 // It is impossible to mock the setting of onu_cfg.data.onu_state because
993 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
994 // set the onu_cfg.data.onu_state. So a new stub function is created and address
995 // of onu_cfg is passed. This is one-of case where we need to add test specific
996 // code in production code.
997 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Girish Gowdra24297032020-03-23 12:32:37 -0700998#else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000999 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Girish Gowdra24297032020-03-23 12:32:37 -07001000#endif
1001 OPENOLT_LOG(INFO, openolt_log_id, "Activate ONU : old state = %d, current state = %d\n",
1002 onu_cfg.data.onu_old_state, onu_cfg.data.onu_state);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001003 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001004 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) {
1005 OPENOLT_LOG(INFO, openolt_log_id, "ONU is already in ACTIVE state, \
1006not processing this request for pon_intf=%d onu_id=%d\n", intf_id, onu_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001007 return Status::OK;
Girish Gowdra24297032020-03-23 12:32:37 -07001008 } else if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_NOT_CONFIGURED &&
1009 onu_cfg.data.onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1010 // We need the ONU to be in NOT_CONFIGURED or INACTIVE state to further process the request
1011 OPENOLT_LOG(ERROR, openolt_log_id, "ONU in an invalid state to process the request, \
1012state=%d pon_intf=%d onu_id=%d\n", onu_cfg.data.onu_state, intf_id, onu_id);
1013 return bcm_to_grpc_err(err, "Failed to activate ONU, invalid ONU state");
1014 }
1015 } else {
1016 // This should never happen. BAL GET should succeed for non-existant ONUs too. The state of such ONUs will be NOT_CONFIGURED
1017 OPENOLT_LOG(ERROR, openolt_log_id, "ONU state query failed pon_intf=%d onu_id=%d\n", intf_id, onu_id);
1018 return bcm_to_grpc_err(err, "onu get failed");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001019 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001020
Girish Gowdra24297032020-03-23 12:32:37 -07001021 // If the ONU is not configured at all we need to first configure it
1022 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_NOT_CONFIGURED) {
1023 OPENOLT_LOG(INFO, openolt_log_id, "Configuring ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001024vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Girish Gowdra24297032020-03-23 12:32:37 -07001025 vendor_specific_to_str(vendor_specific).c_str(), pir);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001026
Girish Gowdra24297032020-03-23 12:32:37 -07001027 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1028 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1029 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1030 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1031 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1032 /*set burst and data profiles to fec disabled*/
1033 if (board_technology == "XGS-PON") {
1034 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1035 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1036 } else if (board_technology == "GPON") {
1037 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1038 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1039 }
1040 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1041 if (err != BCM_ERR_OK) {
1042 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to configure ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
1043 return bcm_to_grpc_err(err, "Failed to configure ONU");
1044 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001045 }
Girish Gowdra24297032020-03-23 12:32:37 -07001046
1047 // Now that the ONU is configured, move the ONU to ACTIVE state
1048 memset(&onu_cfg, 0, sizeof(bcmolt_onu_cfg));
1049 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1050 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1051 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
1052 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
1053 onu_state, BCMOLT_ONU_OPERATION_ACTIVE);
1054 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001055 if (err != BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001056 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 +00001057 return bcm_to_grpc_err(err, "Failed to activate ONU");
1058 }
Girish Gowdra24297032020-03-23 12:32:37 -07001059 // ONU will eventually get activated after we have submitted the operation request. The adapter will receive an asynchronous
1060 // ONU_ACTIVATION_COMPLETED_INDICATION
1061
1062 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 +00001063
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001064 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001065}
1066
Jonathan Davis70c21812018-07-19 15:32:10 -04001067Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1068 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001069 bcmos_errno err = BCM_ERR_OK;
1070 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1071 bcmolt_onu_cfg onu_cfg;
1072 bcmolt_onu_key onu_key; /**< Object key. */
1073 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001074
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001075 onu_key.onu_id = onu_id;
1076 onu_key.pon_ni = intf_id;
1077 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1078 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001079 #ifdef TEST_MODE
1080 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1081 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1082 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1083 // of onu_cfg is passed. This is one-of case where we need to add test specific
1084 // code in production code.
1085 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001086 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001087 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001088 #endif
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301089 onu_state = onu_cfg.data.onu_state;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001090 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001091 switch (onu_state) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001092 case BCMOLT_ONU_STATE_ACTIVE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001093 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001094 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001095 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1096 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1097 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001098 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 +00001099 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1100 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301101 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 +00001102 break;
1103 }
Jonathan Davis70c21812018-07-19 15:32:10 -04001104 }
1105
1106 return Status::OK;
1107}
1108
1109Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001110 const char *vendor_id, const char *vendor_specific) {
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301111 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301112 bcmolt_onu_state onu_state;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001113
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001114 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 -05001115 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1116
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001117 // Need to deactivate before removing it (BAL rules)
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001118 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301119
1120 err = get_onu_status((bcmolt_interface)intf_id, onu_id, &onu_state);
1121 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001122 if (onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1123 OPENOLT_LOG(INFO, openolt_log_id, "waiting for onu deactivate complete response: intf_id=%d, onu_id=%d\n",
1124 intf_id, onu_id);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301125 err = wait_for_onu_deactivate_complete(intf_id, onu_id);
1126 if (err) {
1127 OPENOLT_LOG(ERROR, openolt_log_id, "failed to delete onu intf_id %d, onu_id %d\n",
1128 intf_id, onu_id);
1129 return bcm_to_grpc_err(err, "Failed to delete ONU");
1130 }
1131 }
Girish Gowdra24297032020-03-23 12:32:37 -07001132 else {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301133 OPENOLT_LOG(INFO, openolt_log_id, "Onu is Inactive, onu_id: %d, not waiting for onu deactivate complete response\n",
1134 intf_id);
1135 }
1136 }
1137 else {
1138 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch Onu status, onu_id = %d, intf_id = %d, err = %s\n",
1139 onu_id, intf_id, bcmos_strerror(err));
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301140 return bcm_to_grpc_err(err, "Failed to delete ONU");
1141 }
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001142
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001143 bcmolt_onu_cfg cfg_obj;
1144 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001145
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001146 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 -04001147 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001148
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001149 key.onu_id = onu_id;
1150 key.pon_ni = intf_id;
1151 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001152
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301153 err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001154 if (err != BCM_ERR_OK)
1155 {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001156 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 -04001157 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1158 }
1159
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301160 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 +00001161 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001162}
1163
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001164#define MAX_CHAR_LENGTH 20
1165#define MAX_OMCI_MSG_LENGTH 44
1166Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001167 bcmolt_bin_str buf = {};
1168 bcmolt_onu_cpu_packets omci_cpu_packets;
1169 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001170
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001171 key.pon_ni = intf_id;
1172 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001173
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001174 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1175 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1176 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001177
1178 // ???
1179 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1180 buf.len = MAX_OMCI_MSG_LENGTH;
1181 } else {
1182 buf.len = pkt.size()/2;
1183 }
1184
1185 /* Send the OMCI packet using the BAL remote proxy API */
1186 uint16_t idx1 = 0;
1187 uint16_t idx2 = 0;
1188 uint8_t arraySend[buf.len];
1189 char str1[MAX_CHAR_LENGTH];
1190 char str2[MAX_CHAR_LENGTH];
1191 memset(&arraySend, 0, buf.len);
1192
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001193 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1194 sprintf(str1,"%c", pkt[idx1]);
1195 sprintf(str2,"%c", pkt[++idx1]);
1196 strcat(str1,str2);
1197 arraySend[idx2] = strtol(str1, NULL, 16);
1198 }
1199
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001200 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1201 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001202
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001203 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1204 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1205 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001206
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001207 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001208 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001209 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 +00001210 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001211 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001212 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 -05001213 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001214 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001215 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001216
1217 return Status::OK;
1218}
1219
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001220Status 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 +00001221 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1222 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1223 bcmolt_bin_str buf = {};
1224 bcmolt_gem_port_id gem_port_id_array[1];
1225 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001226
Craig Lutgen967a1d02018-11-27 10:41:51 -06001227 if (port_no > 0) {
1228 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001229 if (gemport_id == 0) {
1230 bcmos_fastlock_lock(&data_lock);
1231 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1232 // Pick any flow that is mapped with the same port_no.
1233 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1234 if (it != port_to_flows.end() && !it->second.empty()) {
1235 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1236 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1237 if (fit != flowid_to_gemport.end()) {
1238 found = true;
1239 gemport_id = fit->second;
1240 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001241 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001242 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001243
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001244 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001245 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 -08001246 onu_id, port_no, intf_id);
1247 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1248 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001249 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 -08001250 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001251 }
1252
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001253 gem_port_id_array[0] = gemport_id;
1254 gem_port_list.len = 1;
1255 gem_port_list.arr = gem_port_id_array;
1256 buf.len = pkt.size();
1257 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1258 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1259
1260 /* init the API struct */
1261 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1262 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1263 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1264 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1265 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1266
1267 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1268 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1269
1270 /* call API */
1271 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001272 }
1273 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001274 //TODO: Port No is 0, it is coming sender requirement.
1275 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1276 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001277 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001278 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001279
1280 return Status::OK;
1281}
1282
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001283Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001284 bcmolt_flow_key key = {}; /* declare key */
1285 bcmolt_bin_str buffer = {};
1286 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001287
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001288 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
1289 bcmolt_flow_id flow_id = 0;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001290
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001291 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1292 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1293 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1294 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1295 key.flow_id = flow_id;
1296 else {
Jason Huang09b73ea2020-01-08 17:52:05 +08001297 if (flow_id_counters) {
1298 std::map<flow_pair, int>::iterator it;
1299 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1300 int flow_index = it->first.first;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001301 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1302 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1303 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1304 key.flow_id = flow_index;
1305 break;
1306 }
1307 }
1308 }
1309 else {
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001310 OPENOLT_LOG(ERROR, openolt_log_id, "no flow id found for uplink packetout\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001311 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1312 }
1313 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001314
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001315 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001316
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001317 /* Initialize the API struct. */
1318 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001319
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001320 buffer.len = pkt.size();
1321 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1322 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1323 if (buffer.arr == NULL) {
1324 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1325 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1326 }
1327 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1328
1329 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1330 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001331 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 -05001332 return bcm_to_grpc_err(BCM_ERR_SYSCALL_ERR, "Error sending packets via nni port");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001333 } else {
1334 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1335 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001336
1337 return Status::OK;
1338}
Craig Lutgen967a1d02018-11-27 10:41:51 -06001339Status 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 +00001340 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001341 int32_t alloc_id, int32_t network_intf_id,
1342 int32_t gemport_id, const ::openolt::Classifier& classifier,
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001343 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00001344 int32_t group_id, uint32_t tech_profile_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001345 bcmolt_flow_cfg cfg;
1346 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001347 int32_t o_vid = -1;
1348 bool single_tag = false;
1349 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001350 bcmolt_classifier c_val = { };
1351 bcmolt_action a_val = { };
1352 bcmolt_tm_queue_ref tm_val = { };
1353 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05001354 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001355
Jason Huang09b73ea2020-01-08 17:52:05 +08001356 OPENOLT_LOG(INFO, openolt_log_id, "flow add received for flow_id=%u, flow_type=%s\n", flow_id, flow_type.c_str());
1357
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001358 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001359 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001360 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001361 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001362 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001363 } else if (flow_type.compare(multicast) == 0) {
1364 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001365 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001366 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001367 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001368 }
1369
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001370 BCMOLT_CFG_INIT(&cfg, flow, key);
1371 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001372
Jason Huang09b73ea2020-01-08 17:52:05 +08001373 if (action.cmd().trap_to_host()) {
1374 Status resp = handle_acl_rule_install(onu_id, flow_id, flow_type, access_intf_id,
1375 network_intf_id, gemport_id, classifier);
1376 return resp;
1377 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001378
1379 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1380
1381 if (access_intf_id >= 0 && network_intf_id >= 0) {
1382 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1383 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1384 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08001385 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1386 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001387 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1388 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1389 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1390 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1391 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001392 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001393 } else {
1394 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
1395 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001396 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001397
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001398 if (onu_id >= 0) {
1399 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
1400 }
1401 if (gemport_id >= 0) {
1402 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
1403 }
1404 if (gemport_id >= 0 && port_no != 0) {
1405 bcmos_fastlock_lock(&data_lock);
1406 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
1407 port_to_flows[port_no].insert(key.flow_id);
1408 flowid_to_gemport[key.flow_id] = gemport_id;
1409 }
1410 else
1411 {
1412 flowid_to_port[key.flow_id] = port_no;
1413 }
1414 bcmos_fastlock_unlock(&data_lock, 0);
1415 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001416 if (gemport_id >= 0 && access_intf_id >= 0) {
1417 // Update the flow_to_acl_map. Note that since this is a datapath flow, acl_id is -1
1418 // This info is needed during flow remove where we need to retrieve the gemport_id
1419 // and access_intf id for the given flow id and flow direction.
1420 // After retrieving the ACL ID and GEM PORT ID, we decrement the corresponding
1421 // reference counters for those ACL ID and GEMPORT ID.
1422 acl_id_gem_id_intf_id ac_id_gm_id_if_id(-1, gemport_id, access_intf_id);
1423 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
1424 bcmos_fastlock_lock(&data_lock);
1425 flow_to_acl_map[fl_id_fl_dir] = ac_id_gm_id_if_id;
1426 bcmos_fastlock_unlock(&data_lock, 0);
1427 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001428 if (priority_value >= 0) {
1429 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
1430 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301431
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001432 } else { // MULTICAST FLOW
1433 if (group_id >= 0) {
1434 BCMOLT_MSG_FIELD_SET(&cfg, group_id, group_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001435 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001436 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1437 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001438 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001439
1440 {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001441 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001442 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001443 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
1444 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001445 }
1446
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001447 if (classifier.dst_mac().size() > 0) {
1448 bcmos_mac_address d_mac = {};
1449 bcmos_mac_address_init(&d_mac);
1450 memcpy(d_mac.u8, classifier.dst_mac().data(), sizeof(d_mac.u8));
1451 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_mac %02x:%02x:%02x:%02x:%02x:%02x\n", d_mac.u8[0],
1452 d_mac.u8[1], d_mac.u8[2], d_mac.u8[3], d_mac.u8[4], d_mac.u8[5]);
1453 BCMOLT_FIELD_SET(&c_val, classifier, dst_mac, d_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001454 }
1455
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001456 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001457 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001458 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001459 }
1460 */
1461
1462 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001463 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
1464 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001465 }
1466
1467 /*
1468 if (classifier.dst_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001469 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_ip, classifier.dst_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001470 }
1471
1472 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001473 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001474 }
1475 */
1476
1477 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001478 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
1479 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001480 }
1481
1482 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001483 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
1484 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001485 }
1486
1487 if (!classifier.pkt_tag_type().empty()) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001488 if (classifier.o_vid()) {
1489 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
1490 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
1491 }
1492
1493 if (classifier.i_vid()) {
1494 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
1495 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
1496 }
1497
1498 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
1499 if (classifier.pkt_tag_type().compare("untagged") == 0) {
1500 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
1501 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
1502 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
1503 single_tag = true;
1504
1505 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301506 // OpenOlt adapter will send 0xFF in case of no pbit classification
1507 // If it is any other value (0 to 7), it is for outer pbit classification.
1508 // OpenFlow protocol does not provide inner pbit classification (in case of double tagged packets),
1509 // and VOLTHA has not used any workaround to solve this problem (for ex: use metadata field).
1510 // Also there exists no use case for i-pbit classification, so we can safely ignore this for now.
1511 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001512 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301513 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001514 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
1515 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001516
Jason Huang09b73ea2020-01-08 17:52:05 +08001517 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301518 // Same comments as in case of "single_tag" packets.
1519 // 0xFF means no pbit classification, otherwise a valid PCP (0 to 7).
1520 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001521 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301522 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001523 }
1524 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001525 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001526 }
1527
Jason Huang09b73ea2020-01-08 17:52:05 +08001528 const ::openolt::ActionCmd& cmd = action.cmd();
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001529
Jason Huang09b73ea2020-01-08 17:52:05 +08001530 if (cmd.add_outer_tag()) {
1531 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
1532 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001533 }
1534
Jason Huang09b73ea2020-01-08 17:52:05 +08001535 if (cmd.remove_outer_tag()) {
1536 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
1537 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
1538 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301539
Jason Huang09b73ea2020-01-08 17:52:05 +08001540 if (action.o_vid()) {
1541 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
1542 o_vid = action.o_vid();
1543 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
1544 }
1545
1546 if (action.o_pbits()) {
1547 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
1548 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
1549 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301550
Jason Huang09b73ea2020-01-08 17:52:05 +08001551 if (action.i_vid()) {
1552 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
1553 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
1554 }
1555
1556 if (action.i_pbits()) {
1557 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
1558 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
1559 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301560
Jason Huang09b73ea2020-01-08 17:52:05 +08001561 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
1562
Shad Ansari39739bc2018-09-13 21:38:37 +00001563 if ((access_intf_id >= 0) && (onu_id >= 0)) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001564 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
1565 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00001566 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 +00001567
Jason Huang09b73ea2020-01-08 17:52:05 +08001568 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1569 // Queue 0 on DS subscriber scheduler
1570 tm_val.queue_id = 0;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001571
Jason Huang09b73ea2020-01-08 17:52:05 +08001572 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1573 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1574 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001575
Jason Huang09b73ea2020-01-08 17:52:05 +08001576 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1577 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1578 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001579
Jason Huang09b73ea2020-01-08 17:52:05 +08001580 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1581 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
1582 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 +00001583
Jason Huang09b73ea2020-01-08 17:52:05 +08001584 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1585 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1586 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1587 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 +00001588
Jason Huang09b73ea2020-01-08 17:52:05 +08001589 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
1590 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1591 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1592 }
1593 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
1594 // NNI Scheduler ID
1595 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1596 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1597 // Queue 0 on NNI scheduler
1598 tm_val.queue_id = 0;
1599 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1600 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1601 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001602
Jason Huang09b73ea2020-01-08 17:52:05 +08001603 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 +00001604 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1605 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1606
Jason Huang09b73ea2020-01-08 17:52:05 +08001607 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1608 /* Fetch TM QMP ID mapped to US NNI scheduler */
1609 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
1610 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1611 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1612 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1613 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 +00001614
Jason Huang09b73ea2020-01-08 17:52:05 +08001615 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 +00001616 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1617 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001618 }
Shad Ansari39739bc2018-09-13 21:38:37 +00001619 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301620 } else {
1621 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1622 tm_val.queue_id = 0;
1623
1624 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
1625 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1626 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
1627
1628 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1629 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
1630 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00001631 }
1632
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001633 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001634
1635 // BAL 3.1 supports statistics only for unicast flows.
1636 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1637 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
1638 }
1639
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001640#ifdef FLOW_CHECKER
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001641 //Flow Checker, To avoid duplicate flow.
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001642 if (flow_id_counters != 0) {
1643 bool b_duplicate_flow = false;
Jason Huang09b73ea2020-01-08 17:52:05 +08001644 std::map<flow_pair, int>::iterator it;
1645
1646 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1647 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(it->first.first, it->first.second, ONU_ID)) && \
1648 (key.flow_type == it->first.second) && \
1649 (cfg.data.svc_port_id == get_flow_status(it->first.first, it->first.second, SVC_PORT_ID)) && \
1650 (cfg.data.priority == get_flow_status(it->first.first, it->first.second, PRIORITY)) && \
1651 (cfg.data.cookie == get_flow_status(it->first.first, it->first.second, COOKIE)) && \
1652 (cfg.data.ingress_intf.intf_type == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_TYPE)) && \
1653 (cfg.data.ingress_intf.intf_id == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_ID)) && \
1654 (cfg.data.egress_intf.intf_type == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_TYPE)) && \
1655 (cfg.data.egress_intf.intf_id == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_ID)) && \
1656 (c_val.o_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_VID)) && \
1657 (c_val.o_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_PBITS)) && \
1658 (c_val.i_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_VID)) && \
1659 (c_val.i_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_PBITS)) && \
1660 (c_val.ether_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_ETHER_TYPE)) && \
1661 (c_val.ip_proto == get_flow_status(it->first.first, it->first.second, CLASSIFIER_IP_PROTO)) && \
1662 (c_val.src_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_SRC_PORT)) && \
1663 (c_val.dst_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_DST_PORT)) && \
1664 (c_val.pkt_tag_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_PKT_TAG_TYPE)) && \
1665 (cfg.data.egress_qos.type == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TYPE)) && \
1666 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_QUEUE_ID)) && \
1667 (cfg.data.egress_qos.tm_sched.id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TM_SCHED_ID)) && \
1668 (a_val.cmds_bitmask == get_flow_status(it->first.first, it->first.second, ACTION_CMDS_BITMASK)) && \
1669 (a_val.o_vid == get_flow_status(it->first.first, it->first.second, ACTION_O_VID)) && \
1670 (a_val.i_vid == get_flow_status(it->first.first, it->first.second, ACTION_I_VID)) && \
1671 (a_val.o_pbits == get_flow_status(it->first.first, it->first.second, ACTION_O_PBITS)) && \
1672 (a_val.i_pbits == get_flow_status(it->first.first, it->first.second, ACTION_I_PBITS)) && \
1673 (cfg.data.state == get_flow_status(it->first.first, it->first.second, STATE)) && \
1674 (cfg.data.group_id == get_flow_status(it->first.first, it->first.second, GROUP_ID));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001675#ifdef SHOW_FLOW_PARAM
1676 // Flow Parameter
1677 FLOW_PARAM_LOG();
1678#endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001679 if (b_duplicate_flow) {
1680 FLOW_LOG(WARNING, "Flow duplicate", 0);
1681 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
1682 }
1683 }
1684 }
1685#endif
1686
1687 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
1688 if (err) {
1689 FLOW_LOG(ERROR, "Flow add failed", err);
1690 return bcm_to_grpc_err(err, "flow add failed");
1691 } else {
1692 FLOW_LOG(INFO, "Flow add ok", err);
1693 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08001694 flow_map[std::pair<int, int>(key.flow_id,key.flow_type)] = flow_map.size();
1695 flow_id_counters = flow_map.size();
1696 if (gemport_id > 0 && access_intf_id >= 0) {
1697 gem_id_intf_id gem_intf(gemport_id, access_intf_id);
1698 if (gem_ref_cnt.count(gem_intf) > 0) {
1699 // The gem port is already installed
1700 // Increment the ref counter indicating number of flows referencing this gem port
1701 gem_ref_cnt[gem_intf]++;
1702 OPENOLT_LOG(DEBUG, openolt_log_id, "incremented gem_ref_cnt, gem_ref_cnt=%d\n", gem_ref_cnt[gem_intf]);
1703 } else {
1704 // Initialize the refence count for the gemport.
1705 gem_ref_cnt[gem_intf] = 1;
1706 OPENOLT_LOG(DEBUG, openolt_log_id, "initialized gem_ref_cnt\n");
1707 }
1708 } else {
1709 OPENOLT_LOG(DEBUG, openolt_log_id, "not incrementing gem_ref_cnt flow_id=%d gemport_id=%d access_intf_id=%d\n", flow_id, gemport_id, access_intf_id);
1710 }
1711
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001712 bcmos_fastlock_unlock(&data_lock, 0);
1713 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04001714
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001715 return Status::OK;
1716}
1717
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001718Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
1719
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001720 bcmolt_flow_cfg cfg;
1721 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001722
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001723 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001724 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001725 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001726 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001727 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001728 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001729 } else if(flow_type.compare(multicast) == 0) {
1730 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001731 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001732 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001733 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
1734 }
1735
Jason Huang09b73ea2020-01-08 17:52:05 +08001736 OPENOLT_LOG(INFO, openolt_log_id, "flow remove received for flow_id=%u, flow_type=%s\n",
1737 flow_id, flow_type.c_str());
1738
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001739 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08001740 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
1741 int32_t gemport_id = -1;
1742 int32_t intf_id = -1;
1743 int16_t acl_id = -1;
1744 if (flow_to_acl_map.count(fl_id_fl_dir) > 0) {
1745 acl_id_gem_id_intf_id ac_id_gm_id_if_id = flow_to_acl_map[fl_id_fl_dir];
1746 acl_id = std::get<0>(ac_id_gm_id_if_id);
1747 gemport_id = std::get<1>(ac_id_gm_id_if_id);
1748 intf_id = std::get<2>(ac_id_gm_id_if_id);
1749 // cleanup acl only if it is a valid acl. If not valid acl, it may be datapath flow.
1750 if (acl_id >= 0) {
1751 Status resp = handle_acl_rule_cleanup(acl_id, gemport_id, intf_id, flow_type);
1752 bcmos_fastlock_unlock(&data_lock, 0);
1753 if (resp.ok()) {
1754 OPENOLT_LOG(INFO, openolt_log_id, "acl removed ok for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
1755 flow_to_acl_map.erase(fl_id_fl_dir);
1756 } else {
1757 OPENOLT_LOG(ERROR, openolt_log_id, "acl remove error for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
1758 }
1759 return resp;
1760 }
1761 }
1762
Craig Lutgen967a1d02018-11-27 10:41:51 -06001763 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001764 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06001765 flowid_to_gemport.erase(key.flow_id);
1766 port_to_flows[port_no].erase(key.flow_id);
1767 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
1768 }
1769 else
1770 {
1771 flowid_to_port.erase(key.flow_id);
1772 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001773 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001774
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001775 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001776
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001777 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001778 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001779 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 -04001780 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
1781 }
1782
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001783 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08001784 if (flow_id_counters != 0) {
1785 std::map<flow_pair, int>::iterator it;
1786 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1787 if (it->first.first == flow_id && it->first.second == key.flow_type) {
1788 flow_id_counters -= 1;
1789 flow_map.erase(it);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001790 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001791 }
1792 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001793 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
1794
1795 clear_gem_port(gemport_id, intf_id);
1796
1797 flow_to_acl_map.erase(fl_id_fl_dir);
1798
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001799 bcmos_fastlock_unlock(&data_lock, 0);
1800
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001801 return Status::OK;
1802}
1803
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001804bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
1805 bcmos_errno err;
1806 bcmolt_tm_sched_cfg tm_sched_cfg;
1807 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
1808 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
1809
Jason Huangbf45ffb2019-10-30 17:29:02 +08001810 //check TM scheduler has configured or not
1811 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
1812 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001813 #ifdef TEST_MODE
1814 // It is impossible to mock the setting of tm_sched_cfg.data.state because
1815 // the actual bcmolt_cfg_get passes the address of tm_sched_cfg.hdr and we cannot
1816 // set the tm_sched_cfg.data.state. So a new stub function is created and address
1817 // of tm_sched_cfg is passed. This is one-of case where we need to add test specific
1818 // code in production code.
1819 err = bcmolt_cfg_get__tm_sched_stub(dev_id, &tm_sched_cfg);
1820 #else
Jason Huangbf45ffb2019-10-30 17:29:02 +08001821 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001822 #endif
Jason Huangbf45ffb2019-10-30 17:29:02 +08001823 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001824 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 +08001825 return err;
1826 }
1827 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
1828 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
1829 return BCM_ERR_OK;
1830 }
1831
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001832 // bcmbal_tm_sched_owner
1833 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
1834
1835 /**< The output of the tm_sched object instance */
1836 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
1837
1838 if (direction.compare(upstream) == 0) {
1839 // In upstream it is NNI scheduler
1840 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
1841 } else if (direction.compare(downstream) == 0) {
1842 // In downstream it is PON scheduler
1843 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
1844 }
1845
1846 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
1847
1848 // bcmbal_tm_sched_type
1849 // set the deafult policy to strict priority
1850 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
1851
1852 // num_priorities: Max number of strict priority scheduling elements
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001853 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, NUM_OF_PRIORITIES);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001854
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001855 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
1856 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001857 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
1858 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001859 return err;
1860 }
1861
1862 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
1863 direction.c_str(), tm_sched_key.id, intf_id);
1864 return BCM_ERR_OK;
1865}
1866
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001867bcmos_errno CreateSched(std::string direction, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t port_no,
1868 uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00001869 tech_profile::SchedulingPolicy sched_policy, tech_profile::TrafficShapingInfo tf_sh_info,
1870 uint32_t tech_profile_id) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001871
1872 bcmos_errno err;
1873
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001874 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001875 bcmolt_tm_sched_cfg tm_sched_cfg;
1876 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
Burak Gurdag2f2618c2020-04-23 13:20:30 +00001877 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 -04001878
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001879 // bcmbal_tm_sched_owner
1880 // In downstream it is sub_term scheduler
1881 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001882
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001883 /**< The output of the tm_sched object instance */
1884 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001885
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001886 // bcmbal_tm_sched_parent
1887 // The parent for the sub_term scheduler is the PON scheduler in the downstream
1888 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
1889 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 +00001890 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001891 be achieved using the' virtual' type of attachment.
1892 tm_sched_owner.u.sub_term.intf_id = intf_id;
1893 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
1894 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001895
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001896 // bcmbal_tm_sched_type
1897 // set the deafult policy to strict priority
1898 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001899
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001900 // num_priorities: Max number of strict priority scheduling elements
1901 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001902
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001903 // bcmbal_tm_shaping
1904 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
1905 uint32_t cir = tf_sh_info.cir();
1906 uint32_t pir = tf_sh_info.pir();
1907 uint32_t burst = tf_sh_info.pbs();
1908 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
1909 cir, pir, burst);
1910 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
1911 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
1912 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
1913 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
1914 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
1915 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001916 }
1917
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001918 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001919 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001920 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001921intf_id %d, onu_id %d, uni_id %d, port_no %u, err = %s\n", tm_sched_key.id, intf_id, onu_id, uni_id, \
1922port_no, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001923 return err;
1924 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001925 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
1926uni_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 -08001927
1928 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001929 bcmolt_itupon_alloc_cfg cfg;
1930 bcmolt_itupon_alloc_key key = { };
1931 key.pon_ni = intf_id;
1932 key.alloc_id = alloc_id;
1933 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
Burak Gurdag03919c72020-02-04 22:46:57 +00001934 int pir_bw = tf_sh_info.pir()*125; // conversion from kbps to bytes/sec
1935 int cir_bw = tf_sh_info.cir()*125; // conversion from kbps to bytes/sec
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001936 //offset to match bandwidth granularity
1937 int offset_pir_bw = pir_bw%bw_granularity;
1938 int offset_cir_bw = cir_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001939
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001940 pir_bw = pir_bw - offset_pir_bw;
1941 cir_bw = cir_bw - offset_cir_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001942
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001943 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001944
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001945 switch (additional_bw) {
1946 case 2: //AdditionalBW_BestEffort
1947 if (pir_bw == 0) {
1948 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
1949%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001950 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001951 } else if (pir_bw < cir_bw) {
1952 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
1953bandwidth (%d)\n", pir_bw, cir_bw);
1954 return BCM_ERR_PARM;
1955 } else if (pir_bw == cir_bw) {
1956 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
1957bandwidth for additional bandwidth eligibility of type best_effort\n");
1958 return BCM_ERR_PARM;
1959 }
1960 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
1961 break;
1962 case 1: //AdditionalBW_NA
1963 if (pir_bw == 0) {
1964 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
1965%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
1966 return BCM_ERR_PARM;
1967 } else if (cir_bw == 0) {
1968 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
1969additional bandwidth eligibility of type Non-Assured (NA)\n");
1970 return BCM_ERR_PARM;
1971 } else if (pir_bw < cir_bw) {
1972 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
1973bandwidth (%d)\n", pir_bw, cir_bw);
1974 return BCM_ERR_PARM;
1975 } else if (pir_bw == cir_bw) {
1976 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
1977bandwidth for additional bandwidth eligibility of type non_assured\n");
1978 return BCM_ERR_PARM;
1979 }
1980 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
1981 break;
1982 case 0: //AdditionalBW_None
1983 if (pir_bw == 0) {
1984 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
198516000 bytes/sec\n");
1986 return BCM_ERR_PARM;
1987 } else if (cir_bw == 0) {
1988 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
1989for additional bandwidth eligibility of type None\n");
1990 return BCM_ERR_PARM;
1991 } else if (pir_bw > cir_bw) {
1992 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
1993for additional bandwidth eligibility of type None\n");
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001994 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001995bandwidth in None eligibility\n", pir_bw);
1996 cir_bw = pir_bw;
1997 } else if (pir_bw < cir_bw) {
1998 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
1999bandwidth (%d)\n", pir_bw, cir_bw);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002000 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002001bandwidth in None eligibility\n", pir_bw);
2002 cir_bw = pir_bw;
2003 }
2004 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2005 break;
2006 default:
2007 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002008 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002009 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2010 in a fine granularity. */
2011 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
2012 /* Fixed Bandwidth with no critical requirement of shaping */
2013 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, 0);
2014 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
2015 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, cir_bw);
2016 /* Maximum allocated bandwidth allowed for this alloc ID */
2017 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
2018 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002019 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002020 for skipped allocations during quiet window */
2021 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2022 /**< Allocation Profile index for CBR non-RT Bandwidth */
2023 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2024 /**< Allocation Profile index for CBR RT Bandwidth */
2025 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2026 /**< Alloc ID Weight used in case of Extended DBA mode */
2027 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2028 /**< Alloc ID Priority used in case of Extended DBA mode */
2029 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2030 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002031
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002032 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002033 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002034 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002035port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002036 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002037 }
Girish Gowdra96461052019-11-22 20:13:59 +05302038
2039 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
2040 if (err) {
2041 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2042port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
2043 return err;
2044 }
2045
2046 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
2047port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
2048
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002049 }
2050
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002051 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002052}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002053
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002054Status CreateTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2055 uint32_t intf_id = traffic_scheds->intf_id();
2056 uint32_t onu_id = traffic_scheds->onu_id();
2057 uint32_t uni_id = traffic_scheds->uni_id();
2058 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002059 std::string direction;
2060 unsigned int alloc_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002061 tech_profile::SchedulerConfig sched_config;
2062 tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002063 uint32_t priority;
2064 uint32_t weight;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002065 tech_profile::SchedulingPolicy sched_policy;
2066 tech_profile::TrafficShapingInfo traffic_shaping_info;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002067 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002068 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002069
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002070 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2071 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002072
2073 direction = GetDirection(traffic_sched.direction());
2074 if (direction.compare("direction-not-supported") == 0)
2075 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2076
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002077 alloc_id = traffic_sched.alloc_id();
2078 sched_config = traffic_sched.scheduler();
2079 additional_bw = sched_config.additional_bw();
2080 priority = sched_config.priority();
2081 weight = sched_config.weight();
2082 sched_policy = sched_config.sched_policy();
2083 traffic_shaping_info = traffic_sched.traffic_shaping_info();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002084 tech_profile_id = traffic_sched.tech_profile_id();
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002085 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002086 sched_policy, traffic_shaping_info, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002087 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002088 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002089 return bcm_to_grpc_err(err, "Failed to create scheduler");
2090 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002091 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002092 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002093}
Jonathan Davis70c21812018-07-19 15:32:10 -04002094
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002095bcmos_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 -04002096
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002097 bcmos_errno err;
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302098 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302099 bcmolt_status los_status;
Girish Gowdra96461052019-11-22 20:13:59 +05302100 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002101
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002102 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002103 bcmolt_itupon_alloc_cfg cfg;
2104 bcmolt_itupon_alloc_key key = { };
2105 key.pon_ni = intf_id;
2106 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302107 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002108
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002109 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002110 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2111 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002112 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2113 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002114 return err;
2115 }
Girish Gowdra96461052019-11-22 20:13:59 +05302116
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302117 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302118 if (err == BCM_ERR_OK) {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302119 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_OFF) {
2120 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 +05302121 intf_id);
2122 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2123 if (err) {
2124 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2125 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
2126 return err;
2127 }
2128 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302129 else if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_ON) {
2130 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is enabled but LoS status is ON, not waiting for alloc cfg clear response\n",
2131 intf_id);
2132 }
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302133 else if (state == BCMOLT_INTERFACE_STATE_INACTIVE) {
2134 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is disabled, not waiting for alloc cfg clear response\n",
2135 intf_id);
2136 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302137 } else {
2138 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 +05302139 intf_id, bcmos_strerror(err));
Girish Gowdra96461052019-11-22 20:13:59 +05302140 return err;
2141 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002142 } else if (direction == downstream) {
2143 bcmolt_tm_sched_cfg cfg;
2144 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002145
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002146 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2147 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302148 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002149 } else {
2150 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2151 return BCM_ERR_OK;
2152 }
Girish Gowdra96461052019-11-22 20:13:59 +05302153
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002154 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2155 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2156 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002157 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002158intf_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 +00002159 return err;
2160 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002161 }
2162
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002163 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d, tech_profile_id %d\n",
2164 direction.c_str(), sched_id, intf_id, onu_id, tech_profile_id);
2165 free_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002166 return BCM_ERR_OK;
2167}
2168
2169Status RemoveTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2170 uint32_t intf_id = traffic_scheds->intf_id();
2171 uint32_t onu_id = traffic_scheds->onu_id();
2172 uint32_t uni_id = traffic_scheds->uni_id();
2173 std::string direction;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002174 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002175 bcmos_errno err;
2176
2177 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2178 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002179
2180 direction = GetDirection(traffic_sched.direction());
2181 if (direction.compare("direction-not-supported") == 0)
2182 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2183
2184 int alloc_id = traffic_sched.alloc_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002185 int tech_profile_id = traffic_sched.tech_profile_id();
2186 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002187 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002188 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002189 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2190 }
2191 }
2192 return Status::OK;
2193}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002194
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002195bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2196 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002197 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002198 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2199 bcmolt_tm_qmp_key tm_qmp_key;
2200 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002201
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002202 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2203 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002204 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed tm queue mapping profile count is 16.\n");
2205 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002206 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002207
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002208 tm_qmp_key.id = tm_qmp_id;
2209 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2210 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2211 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002212
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002213 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2214 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2215 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002216 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2217 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002218
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002219 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002220 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002221 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2222 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002223 return err;
2224 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002225
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002226 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2227 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002228 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002229}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002230
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002231bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2232 bcmos_errno err;
2233 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2234 bcmolt_tm_qmp_key tm_qmp_key;
2235 tm_qmp_key.id = tm_qmp_id;
2236
2237 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2238 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2239 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002240 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2241 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002242 return err;
2243 }
2244
2245 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2246 tm_qmp_key.id);
2247 return BCM_ERR_OK;
2248}
2249
2250bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2251 bcmos_errno err;
2252
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002253 /* Create default queues on the given PON/NNI scheduler */
2254 for (int queue_id = 0; queue_id < NUMBER_OF_DEFAULT_INTERFACE_QUEUES; queue_id++) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002255 bcmolt_tm_queue_cfg tm_queue_cfg;
2256 bcmolt_tm_queue_key tm_queue_key = {};
2257 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2258 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002259 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2260 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2261 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002262
2263 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2264 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2265 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2266
2267 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2268 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002269 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", \
2270 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 +00002271 return err;
2272 }
2273
2274 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2275 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2276 }
2277 return BCM_ERR_OK;
2278}
2279
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002280bcmos_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 +00002281 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 +00002282 bcmos_errno err;
2283 bcmolt_tm_queue_cfg cfg;
2284 bcmolt_tm_queue_key key = { };
2285 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 +00002286gemport_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 +00002287
2288 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002289 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002290
2291 if (priority > 7) {
2292 return BCM_ERR_RANGE;
2293 }
2294
2295 /* FIXME: The upstream queues have to be created once only.
2296 The upstream queues on the NNI scheduler are shared by all subscribers.
2297 When the first scheduler comes in, the queues get created, and are re-used by all others.
2298 Also, these queues should be present until the last subscriber exits the system.
2299 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2300
2301 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2302 for each GEM in TECH PROFILE */
2303 key.id = queue_id_list[priority];
2304
2305 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2306 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2307 key.id = 0;
2308 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2309 }
2310 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2311 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2312 }
2313 else {
2314 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2315 }
2316
2317 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2318
2319 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2320 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
2321
2322 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2323 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002324 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002325sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, tech_profile_id %d, err = %s\n", \
2326 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 +00002327 return err;
2328 }
2329
2330 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 +00002331intf_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 +00002332 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002333}
2334
2335Status CreateTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2336 uint32_t intf_id = traffic_queues->intf_id();
2337 uint32_t onu_id = traffic_queues->onu_id();
2338 uint32_t uni_id = traffic_queues->uni_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002339 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002340 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002341 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002342 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002343 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 +00002344
2345 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2346 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2347 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2348 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2349 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
2350
2351 direction = GetDirection(traffic_queue.direction());
2352 if (direction.compare("direction-not-supported") == 0)
2353 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2354
2355 queues_priority_q[i] = traffic_queue.priority();
2356 queues_pbit_map[i] = traffic_queue.pbit_map();
2357 }
2358
2359 std::vector<uint32_t> tmq_map_profile(8, 0);
2360 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2361 queues_priority_q, COUNT_OF(queues_priority_q));
2362 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002363 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002364
2365 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2366 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002367 err = CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2368 if (err != BCM_ERR_OK) {
2369 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2370 return bcm_to_grpc_err(err, "Failed to create tm queue mapping profile");
2371 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002372 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2373 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2374 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2375 }
2376 }
2377
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002378 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2379 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002380
2381 direction = GetDirection(traffic_queue.direction());
2382 if (direction.compare("direction-not-supported") == 0)
2383 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2384
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002385 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 +00002386
Girish Gowdruf26cf882019-05-01 23:47:58 -07002387 // If the queue exists already, lets not return failure and break the loop.
2388 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002389 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002390 return bcm_to_grpc_err(err, "Failed to create queue");
2391 }
2392 }
2393 return Status::OK;
2394}
2395
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002396bcmos_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 +00002397 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 +00002398 bcmolt_tm_queue_cfg cfg;
2399 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002400 bcmos_errno err;
2401
2402 if (direction == downstream) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002403 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2404 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 +00002405 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002406 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002407 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 -08002408 return BCM_ERR_OK;
2409 }
2410 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002411 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2412 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002413 return BCM_ERR_OK;
2414 }
2415
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002416 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2417 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2418 // Reset the queue id to 0 when using fixed queue.
2419 key.id = 0;
2420 }
2421 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2422 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2423 }
2424 else {
2425 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2426 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002427
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002428 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2429 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002430 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002431 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, queue_id %d, sched_id %d, \
2432tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n",
2433 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 -08002434 return err;
2435 }
2436
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002437 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2438intf_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 -08002439
2440 return BCM_ERR_OK;
2441}
2442
2443Status RemoveTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2444 uint32_t intf_id = traffic_queues->intf_id();
2445 uint32_t onu_id = traffic_queues->onu_id();
2446 uint32_t uni_id = traffic_queues->uni_id();
2447 uint32_t port_no = traffic_queues->port_no();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002448 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002449 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002450 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002451 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002452 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 +00002453
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002454 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2455 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002456
2457 direction = GetDirection(traffic_queue.direction());
2458 if (direction.compare("direction-not-supported") == 0)
2459 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2460
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002461 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 -08002462 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002463 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002464 return bcm_to_grpc_err(err, "Failed to remove queue");
2465 }
Jonathan Davis70c21812018-07-19 15:32:10 -04002466 }
2467
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002468 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 +00002469 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002470 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002471
2472 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
2473 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002474 err = RemoveTrafficQueueMappingProfile(tm_qmp_id);
2475 if (err != BCM_ERR_OK) {
2476 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2477 return bcm_to_grpc_err(err, "Failed to remove tm queue mapping profile");
2478 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002479 }
2480 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002481 clear_qos_type(intf_id, onu_id, uni_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04002482 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04002483}
Jason Huangbf45ffb2019-10-30 17:29:02 +08002484
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002485Status PerformGroupOperation_(const openolt::Group *group_cfg) {
2486
2487 bcmos_errno err;
2488 bcmolt_group_key key = {};
2489 bcmolt_group_cfg grp_cfg_obj;
2490 bcmolt_group_members_update grp_mem_upd;
2491 bcmolt_members_update_command grp_mem_upd_cmd;
2492 bcmolt_group_member_info member_info = {};
2493 bcmolt_group_member_info_list_u8 members = {};
2494 bcmolt_intf_ref interface_ref = {};
2495 bcmolt_egress_qos egress_qos = {};
2496 bcmolt_tm_sched_ref tm_sched_ref = {};
2497 bcmolt_action a_val = {};
2498
2499 uint32_t group_id = group_cfg->group_id();
2500
2501 OPENOLT_LOG(INFO, openolt_log_id, "PerformGroupOperation request received for Group %d\n", group_id);
2502
2503 if (group_id >= 0) {
2504 key.id = group_id;
2505 }
2506 else {
2507 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
2508 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
2509 }
2510
2511 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2512 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
2513
2514 OPENOLT_LOG(INFO, openolt_log_id, "Checking if Group %d exists...\n",group_id);
2515
2516 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
2517 if (err != BCM_ERR_OK) {
2518 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
2519 return bcm_to_grpc_err(err, "Error in querying group");
2520 }
2521
2522 members.len = group_cfg->members_size();
2523
2524 // IMPORTANT: A member cannot be added to a group if the group type is not determined.
2525 // Group type is determined after a flow is assigned to it.
2526 // Therefore, a group must be created first, then a flow (with multicast type) must be assigned to it.
2527 // Only then we can add members to the group.
2528
2529 // if group does not exist, create it and return.
2530 if (grp_cfg_obj.data.state == BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
2531
2532 if (members.len != 0) {
2533 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);
2534 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Non-empty member list given for non-existent group");
2535 } else {
2536
2537 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2538 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, cookie, key.id);
2539
2540 /* Setting group actions and action parameters, if any.
2541 Only remove_outer_tag and translate_inner_tag actions and i_vid action parameter
2542 are supported for multicast groups in BAL 3.1.
2543 */
2544 const ::openolt::Action& action = group_cfg->action();
2545 const ::openolt::ActionCmd &cmd = action.cmd();
2546
2547 bcmolt_action_cmd_id cmd_bmask = BCMOLT_ACTION_CMD_ID_NONE;
2548 if (cmd.remove_outer_tag()) {
2549 OPENOLT_LOG(INFO, openolt_log_id, "Action remove_outer_tag applied to Group %d.\n", group_id);
2550 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
2551 }
2552
2553 if (cmd.translate_inner_tag()) {
2554 OPENOLT_LOG(INFO, openolt_log_id, "Action translate_inner_tag applied to Group %d.\n", group_id);
2555 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG);
2556 }
2557
2558 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, cmd_bmask);
2559
2560 if (action.i_vid()) {
2561 OPENOLT_LOG(INFO, openolt_log_id, "Setting action parameter i_vid=%d for Group %d.\n", action.i_vid(), group_id);
2562 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
2563 }
2564
2565 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, action, a_val);
2566
2567 // Create group
2568 err = bcmolt_cfg_set(dev_id, &(grp_cfg_obj.hdr));
2569
2570 if (BCM_ERR_OK != err) {
2571 BCM_LOG(ERROR, openolt_log_id, "Failed to create Group %d, err = %s (%d)\n", key.id, bcmos_strerror(err), err);
2572 return bcm_to_grpc_err(err, "Error in creating group");
2573 }
2574
2575 BCM_LOG(INFO, openolt_log_id, "Group %d has been created and configured with empty member list.\n", key.id);
2576 return Status::OK;
2577 }
2578 }
2579
2580 // The group already exists. Continue configuring it according to the update member command.
2581
2582 OPENOLT_LOG(INFO, openolt_log_id, "Configuring existing Group %d.\n",group_id);
2583
2584 // MEMBER LIST CONSTRUCTION
2585 // Note that members.len can be 0 here. if the group already exists and the command is SET then sending
2586 // empty list to the group is a legit operation and this actually empties the member list.
2587 members.arr = (bcmolt_group_member_info*)bcmos_calloc((members.len)*sizeof(bcmolt_group_member_info));
2588
2589 if (!members.arr) {
2590 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to allocate memory for group member list.\n");
2591 return grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "Memory exhausted during member list creation");
2592 }
2593
2594 /* SET GROUP MEMBERS UPDATE COMMAND */
2595 openolt::Group::GroupMembersCommand command = group_cfg->command();
2596 switch(command) {
2597 case openolt::Group::SET_MEMBERS :
2598 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_SET;
2599 OPENOLT_LOG(INFO, openolt_log_id, "Setting %d members for Group %d.\n", members.len, group_id);
2600 break;
2601 case openolt::Group::ADD_MEMBERS :
2602 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_ADD;
2603 OPENOLT_LOG(INFO, openolt_log_id, "Adding %d members to Group %d.\n", members.len, group_id);
2604 break;
2605 case openolt::Group::REMOVE_MEMBERS :
2606 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_REMOVE;
2607 OPENOLT_LOG(INFO, openolt_log_id, "Removing %d members from Group %d.\n", members.len, group_id);
2608 break;
2609 default :
2610 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid value %d for group member command.\n", command);
2611 bcmos_free(members.arr);
2612 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group member command");
2613 }
2614
2615 // SET MEMBERS LIST
2616 for (int i = 0; i < members.len; i++) {
2617
2618 if (command == openolt::Group::REMOVE_MEMBERS) {
2619 OPENOLT_LOG(INFO, openolt_log_id, "Removing group member %d from group %d\n",i,key.id);
2620 } else {
2621 OPENOLT_LOG(INFO, openolt_log_id, "Adding group member %d to group %d\n",i,key.id);
2622 }
2623
2624 openolt::GroupMember *member = (openolt::GroupMember *) &group_cfg->members()[i];
2625
2626 // Set member interface type
2627 openolt::GroupMember::InterfaceType if_type = member->interface_type();
2628 switch(if_type){
2629 case openolt::GroupMember::PON :
2630 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_PON);
2631 OPENOLT_LOG(INFO, openolt_log_id, "Interface type PON is assigned to GroupMember %d\n",i);
2632 break;
2633 case openolt::GroupMember::EPON_1G_PATH :
2634 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_1_G);
2635 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_1G is assigned to GroupMember %d\n",i);
2636 break;
2637 case openolt::GroupMember::EPON_10G_PATH :
2638 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_10_G);
2639 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_10G is assigned to GroupMember %d\n",i);
2640 break;
2641 default :
2642 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid interface type value %d for GroupMember %d.\n",if_type,i);
2643 bcmos_free(members.arr);
2644 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface type for a group member");
2645 }
2646
2647 // Set member interface id
2648 if (member->interface_id() >= 0) {
2649 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_id, member->interface_id());
2650 OPENOLT_LOG(INFO, openolt_log_id, "Interface %d is assigned to GroupMember %d\n", member->interface_id(), i);
2651 } else {
2652 bcmos_free(members.arr);
2653 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface id for a group member");
2654 }
2655
2656 // Set member interface_ref
2657 BCMOLT_FIELD_SET(&member_info, group_member_info, intf, interface_ref);
2658
2659 // Set member gem_port_id. This must be a multicast gemport.
2660 if (member->gem_port_id() >= 0) {
2661 BCMOLT_FIELD_SET(&member_info, group_member_info, svc_port_id, member->gem_port_id());
2662 OPENOLT_LOG(INFO, openolt_log_id, "GEM Port %d is assigned to GroupMember %d\n", member->gem_port_id(), i);
2663 } else {
2664 bcmos_free(members.arr);
2665 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid gem port id for a group member");
2666 }
2667
2668 // Set member scheduler id and queue_id
2669 uint32_t tm_sched_id = get_default_tm_sched_id(member->interface_id(), downstream);
2670 OPENOLT_LOG(INFO, openolt_log_id, "Scheduler %d is assigned to GroupMember %d\n", tm_sched_id, i);
2671 BCMOLT_FIELD_SET(&tm_sched_ref, tm_sched_ref, id, tm_sched_id);
2672 BCMOLT_FIELD_SET(&egress_qos, egress_qos, tm_sched, tm_sched_ref);
2673
2674 // We assume that all multicast traffic destined to a PON port is using the same fixed queue.
2675 uint32_t tm_queue_id;
2676 if (member->priority() >= 0 && member->priority() < NUMBER_OF_DEFAULT_INTERFACE_QUEUES) {
2677 tm_queue_id = queue_id_list[member->priority()];
2678 OPENOLT_LOG(INFO, openolt_log_id, "Queue %d is assigned to GroupMember %d\n", tm_queue_id, i);
2679 BCMOLT_FIELD_SET(&egress_qos, egress_qos, type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2680 BCMOLT_FIELD_SET(&egress_qos.u.fixed_queue, egress_qos_fixed_queue, queue_id, tm_queue_id);
2681 } else {
2682 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid fixed queue priority/ID %d for GroupMember %d\n", member->priority(), i);
2683 bcmos_free(members.arr);
2684 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid queue priority for a group member");
2685 }
2686
2687 BCMOLT_FIELD_SET(&member_info, group_member_info, egress_qos, egress_qos);
2688 BCMOLT_ARRAY_ELEM_SET(&(members), i, member_info);
2689 }
2690
2691 BCMOLT_OPER_INIT(&grp_mem_upd, group, members_update, key);
2692 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.members, members);
2693 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.command, grp_mem_upd_cmd);
2694
2695 err = bcmolt_oper_submit(dev_id, &(grp_mem_upd.hdr));
2696 bcmos_free(members.arr);
2697
2698 if (BCM_ERR_OK != err) {
2699 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);
2700 return bcm_to_grpc_err(err, "Failed to submit members update operation for the group");
2701 }
2702
2703 OPENOLT_LOG(INFO, openolt_log_id, "Successfully submitted members update operation for Group %d\n", key.id);
2704
2705 return Status::OK;
2706}