blob: 006e6fb8dadac1e886b4768bcb1356b868868c95 [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,
70 tech_profile::TrafficShapingInfo traffic_shaping_info);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000071static bcmos_errno RemoveSched(int intf_id, int onu_id, int uni_id, int alloc_id, std::string direction);
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, \
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -050073 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id);
74static bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
75 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_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);
156 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_SAME_TECH);
157 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);
162 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
163 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);
183 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_SAME_TECH);
184 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);
189 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
190 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;
759
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400760 err = get_pon_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000761 if (err == BCM_ERR_OK) {
762 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800763 OPENOLT_LOG(WARNING, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000764 return Status::OK;
765 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400766 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000767 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
768 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
769 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
770 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.interval, 5000);
771 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.onu_post_discovery_mode,
772 BCMOLT_ONU_POST_DISCOVERY_MODE_ACTIVATE);
773 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.los, true);
774 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.onu_alarms, true);
775 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.tiwi, true);
776 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.ack_timeout, true);
777 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.sfi, true);
778 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.loki, true);
779 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
780 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
781
782 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
783 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500784 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 +0000785 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
786 }
787 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
788 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500789 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 +0000790 return bcm_to_grpc_err(err, "Failed to enable PON interface");
791 }
792 else {
793 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
794 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
795 CreateDefaultSched(intf_id, downstream);
796 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400797 }
798
799 return Status::OK;
800}
801
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500802Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000803 bcmos_errno err;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400804 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000805 bcmolt_device_key dev_key = { };
806 bcmolt_olt_cfg olt_cfg = { };
807 bcmolt_olt_key olt_key = { };
808 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
809 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500810
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000811 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
812 topo.topology_maps.arr = &topo_map[0];
813 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
814 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
815 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400816 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000817 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400818 #ifdef TEST_MODE
819 // It is impossible to mock the setting of olt_cfg.data.bal_state because
820 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
821 // set the olt_cfg.data.topology. So a new stub function is created and address
822 // of olt_cfg is passed. This is one-of case where we need to test add specific
823 // code in production code.
824 err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
825 #else
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000826 err = bcmolt_cfg_get_mult_retry(dev_id, &olt_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400827 #endif
828 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500829 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 +0000830 return bcm_to_grpc_err(err, "cfg: Failed to query OLT topology");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500831 }
832
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000833 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
834 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500835
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400836 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
837 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000838 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500839
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000840 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
841 num_of_nni_ports,
842 num_of_pon_ports,
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400843 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500844
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000845 uint32_t num_failed_cfg_gets = 0;
Jason Huang09b73ea2020-01-08 17:52:05 +0800846 static std::string openolt_version = firmware_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000847 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
848 dev_key.device_id = devid;
849 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
850 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
851 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
852 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000853 err = bcmolt_cfg_get_mult_retry(dev_id, &dev_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400854 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500855 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 +0000856 num_failed_cfg_gets++;
857 continue;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000858 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500859
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000860 std::string bal_version;
861 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
862 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
863 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
Jason Huang09b73ea2020-01-08 17:52:05 +0800864 firmware_version = "BAL." + bal_version + "__" + openolt_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000865
866 switch(dev_cfg.data.system_mode) {
867 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
868 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
869 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
870 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
871 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
872 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
873 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
874 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
875 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
876 case 20: board_technology = MIXED_TECH; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,MIXED_TECH); break;
877 }
878
879 switch(dev_cfg.data.chip_family) {
Jason Huang09b73ea2020-01-08 17:52:05 +0800880 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X: chip_family = "Maple"; break;
881 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X: chip_family = "Aspen"; break;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000882 }
883
Jason Huang09b73ea2020-01-08 17:52:05 +0800884 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s, family: %s, board_technology: %s\n",
885 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 +0000886
887 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500888 }
889
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000890 /* 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 +0000891 only the devices that retured success*/
892 if (num_failed_cfg_gets == BCM_MAX_DEVS_PER_LINE_CARD) {
893 OPENOLT_LOG(ERROR, openolt_log_id, "device: Query of all the devices failed\n");
894 return bcm_to_grpc_err(err, "device: All devices failed query");
895 }
896
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500897 return Status::OK;
898}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400899
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000900Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000901 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000902 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
903 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
904 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -0500905
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400906 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000907 if (err == BCM_ERR_OK) {
908 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800909 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000910 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
911 CreateDefaultSched(intf_id, upstream);
912 CreateDefaultQueue(intf_id, upstream);
913 return Status::OK;
914 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
915 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
916 return Status::OK;
917 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -0500918 }
919
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000920 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
921 if (set_state) {
922 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
923 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
924 } else {
925 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
926 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
927 }
928 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
929 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500930 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err = %s\n",
931 (set_state)?"enable":"disable", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000932 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
933 }
934 else {
935 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
936 if (set_state) {
937 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
938 CreateDefaultSched(intf_id, upstream);
939 CreateDefaultQueue(intf_id, upstream);
940 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400941 }
942
943 return Status::OK;
944}
945
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -0400946Status DisablePonIf_(uint32_t intf_id) {
Chaitrashree G S73e084d2019-11-20 16:18:59 -0500947 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000948 bcmolt_pon_interface_cfg interface_obj;
Chaitrashree G S73e084d2019-11-20 16:18:59 -0500949 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
950 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -0400951
Chaitrashree G S73e084d2019-11-20 16:18:59 -0500952 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
953 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
954 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_DISABLE);
955
956 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
957 if (err != BCM_ERR_OK) {
958 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable discovery of onu, PON interface %d, err %d\n", intf_id, err);
959 return bcm_to_grpc_err(err, "Failed to disable discovery of onu");
960 }
961
962 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
963 operation, BCMOLT_INTERFACE_OPERATION_INACTIVE);
964
965 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
966 if (err != BCM_ERR_OK) {
967 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 -0400968 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -0400969 }
970
Chaitrashree G S73e084d2019-11-20 16:18:59 -0500971 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled PON interface: %d\n", intf_id);
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -0400972 return Status::OK;
973}
974
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000975Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700976 const char *vendor_id, const char *vendor_specific, uint32_t pir) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000977 bcmos_errno err = BCM_ERR_OK;
978 bcmolt_onu_cfg onu_cfg;
979 bcmolt_onu_key onu_key;
980 bcmolt_serial_number serial_number; /**< ONU serial number */
981 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000982
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000983 onu_key.onu_id = onu_id;
984 onu_key.pon_ni = intf_id;
985 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
986 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -0500987 #ifdef TEST_MODE
988 // It is impossible to mock the setting of onu_cfg.data.onu_state because
989 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
990 // set the onu_cfg.data.onu_state. So a new stub function is created and address
991 // of onu_cfg is passed. This is one-of case where we need to add test specific
992 // code in production code.
993 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
994 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000995 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -0500996 #endif
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400997 if (err == BCM_ERR_OK) {
998 if ((onu_cfg.data.onu_state == BCMOLT_ONU_STATE_PROCESSING ||
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000999 onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) ||
1000 (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_INACTIVE &&
1001 onu_cfg.data.onu_old_state == BCMOLT_ONU_STATE_NOT_CONFIGURED))
1002 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001003 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001004
1005 OPENOLT_LOG(INFO, openolt_log_id, "Enabling ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001006vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001007 vendor_specific_to_str(vendor_specific).c_str(), pir);
1008
1009 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1010 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1011 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1012 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1013 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1014 /*set burst and data profiles to fec disabled*/
1015 if (board_technology == "XGS-PON") {
1016 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1017 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1018 } else if (board_technology == "GPON") {
1019 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1020 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1021 }
1022 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1023 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001024 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to set activate ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001025 return bcm_to_grpc_err(err, "Failed to activate ONU");
1026 }
1027
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001028 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001029}
1030
Jonathan Davis70c21812018-07-19 15:32:10 -04001031Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1032 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001033 bcmos_errno err = BCM_ERR_OK;
1034 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1035 bcmolt_onu_cfg onu_cfg;
1036 bcmolt_onu_key onu_key; /**< Object key. */
1037 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001038
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001039 onu_key.onu_id = onu_id;
1040 onu_key.pon_ni = intf_id;
1041 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1042 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001043 #ifdef TEST_MODE
1044 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1045 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1046 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1047 // of onu_cfg is passed. This is one-of case where we need to add test specific
1048 // code in production code.
1049 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001050 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001051 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001052 #endif
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301053 onu_state = onu_cfg.data.onu_state;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001054 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001055 switch (onu_state) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001056 case BCMOLT_ONU_STATE_ACTIVE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001057 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001058 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001059 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1060 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1061 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001062 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 +00001063 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1064 }
1065 break;
1066 }
Jonathan Davis70c21812018-07-19 15:32:10 -04001067 }
1068
1069 return Status::OK;
1070}
1071
1072Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001073 const char *vendor_id, const char *vendor_specific) {
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301074 bcmos_errno err = BCM_ERR_OK;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001075
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001076 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 -05001077 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1078
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001079 // Need to deactivate before removing it (BAL rules)
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001080 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301081 err = wait_for_onu_deactivate_complete(intf_id, onu_id);
1082 if (err) {
1083 OPENOLT_LOG(ERROR, openolt_log_id, "failed to delete onu intf_id %d, onu_id %d\n",
1084 intf_id, onu_id);
1085 return bcm_to_grpc_err(err, "Failed to delete ONU");
1086 }
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001087
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001088 bcmolt_onu_cfg cfg_obj;
1089 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001090
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001091 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 -04001092 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001093
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001094 key.onu_id = onu_id;
1095 key.pon_ni = intf_id;
1096 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001097
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301098 err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001099 if (err != BCM_ERR_OK)
1100 {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001101 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 -04001102 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1103 }
1104
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001105 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001106}
1107
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001108#define MAX_CHAR_LENGTH 20
1109#define MAX_OMCI_MSG_LENGTH 44
1110Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001111 bcmolt_bin_str buf = {};
1112 bcmolt_onu_cpu_packets omci_cpu_packets;
1113 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001114
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001115 key.pon_ni = intf_id;
1116 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001117
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001118 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1119 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1120 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001121
1122 // ???
1123 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1124 buf.len = MAX_OMCI_MSG_LENGTH;
1125 } else {
1126 buf.len = pkt.size()/2;
1127 }
1128
1129 /* Send the OMCI packet using the BAL remote proxy API */
1130 uint16_t idx1 = 0;
1131 uint16_t idx2 = 0;
1132 uint8_t arraySend[buf.len];
1133 char str1[MAX_CHAR_LENGTH];
1134 char str2[MAX_CHAR_LENGTH];
1135 memset(&arraySend, 0, buf.len);
1136
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001137 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1138 sprintf(str1,"%c", pkt[idx1]);
1139 sprintf(str2,"%c", pkt[++idx1]);
1140 strcat(str1,str2);
1141 arraySend[idx2] = strtol(str1, NULL, 16);
1142 }
1143
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001144 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1145 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001146
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001147 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1148 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1149 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001150
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001151 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001152 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001153 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 +00001154 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001155 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001156 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 -05001157 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001158 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001159 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001160
1161 return Status::OK;
1162}
1163
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001164Status 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 +00001165 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1166 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1167 bcmolt_bin_str buf = {};
1168 bcmolt_gem_port_id gem_port_id_array[1];
1169 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001170
Craig Lutgen967a1d02018-11-27 10:41:51 -06001171 if (port_no > 0) {
1172 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001173 if (gemport_id == 0) {
1174 bcmos_fastlock_lock(&data_lock);
1175 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1176 // Pick any flow that is mapped with the same port_no.
1177 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1178 if (it != port_to_flows.end() && !it->second.empty()) {
1179 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1180 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1181 if (fit != flowid_to_gemport.end()) {
1182 found = true;
1183 gemport_id = fit->second;
1184 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001185 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001186 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001187
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001188 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001189 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 -08001190 onu_id, port_no, intf_id);
1191 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1192 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001193 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 -08001194 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001195 }
1196
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001197 gem_port_id_array[0] = gemport_id;
1198 gem_port_list.len = 1;
1199 gem_port_list.arr = gem_port_id_array;
1200 buf.len = pkt.size();
1201 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1202 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1203
1204 /* init the API struct */
1205 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1206 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1207 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1208 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1209 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1210
1211 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1212 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1213
1214 /* call API */
1215 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001216 }
1217 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001218 //TODO: Port No is 0, it is coming sender requirement.
1219 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1220 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001221 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001222 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001223
1224 return Status::OK;
1225}
1226
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001227Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001228 bcmolt_flow_key key = {}; /* declare key */
1229 bcmolt_bin_str buffer = {};
1230 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001231
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001232 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
1233 bcmolt_flow_id flow_id = 0;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001234
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001235 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1236 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1237 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1238 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1239 key.flow_id = flow_id;
1240 else {
Jason Huang09b73ea2020-01-08 17:52:05 +08001241 if (flow_id_counters) {
1242 std::map<flow_pair, int>::iterator it;
1243 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1244 int flow_index = it->first.first;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001245 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1246 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1247 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1248 key.flow_id = flow_index;
1249 break;
1250 }
1251 }
1252 }
1253 else {
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001254 OPENOLT_LOG(ERROR, openolt_log_id, "no flow id found for uplink packetout\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001255 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1256 }
1257 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001258
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001259 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001260
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001261 /* Initialize the API struct. */
1262 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001263
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001264 buffer.len = pkt.size();
1265 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1266 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1267 if (buffer.arr == NULL) {
1268 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1269 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1270 }
1271 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1272
1273 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1274 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001275 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 -05001276 return bcm_to_grpc_err(BCM_ERR_SYSCALL_ERR, "Error sending packets via nni port");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001277 } else {
1278 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1279 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001280
1281 return Status::OK;
1282}
Craig Lutgen967a1d02018-11-27 10:41:51 -06001283Status 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 +00001284 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001285 int32_t alloc_id, int32_t network_intf_id,
1286 int32_t gemport_id, const ::openolt::Classifier& classifier,
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001287 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie,
1288 int32_t group_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001289 bcmolt_flow_cfg cfg;
1290 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001291 int32_t o_vid = -1;
1292 bool single_tag = false;
1293 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001294 bcmolt_classifier c_val = { };
1295 bcmolt_action a_val = { };
1296 bcmolt_tm_queue_ref tm_val = { };
1297 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05001298 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001299
Jason Huang09b73ea2020-01-08 17:52:05 +08001300 OPENOLT_LOG(INFO, openolt_log_id, "flow add received for flow_id=%u, flow_type=%s\n", flow_id, flow_type.c_str());
1301
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001302 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001303 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001304 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001305 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001306 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001307 } else if (flow_type.compare(multicast) == 0) {
1308 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001309 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001310 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001311 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001312 }
1313
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001314 BCMOLT_CFG_INIT(&cfg, flow, key);
1315 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001316
Jason Huang09b73ea2020-01-08 17:52:05 +08001317 if (action.cmd().trap_to_host()) {
1318 Status resp = handle_acl_rule_install(onu_id, flow_id, flow_type, access_intf_id,
1319 network_intf_id, gemport_id, classifier);
1320 return resp;
1321 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001322
1323 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1324
1325 if (access_intf_id >= 0 && network_intf_id >= 0) {
1326 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1327 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1328 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08001329 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1330 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001331 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1332 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1333 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1334 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1335 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001336 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001337 } else {
1338 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
1339 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001340 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001341
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001342 if (onu_id >= 0) {
1343 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
1344 }
1345 if (gemport_id >= 0) {
1346 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
1347 }
1348 if (gemport_id >= 0 && port_no != 0) {
1349 bcmos_fastlock_lock(&data_lock);
1350 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
1351 port_to_flows[port_no].insert(key.flow_id);
1352 flowid_to_gemport[key.flow_id] = gemport_id;
1353 }
1354 else
1355 {
1356 flowid_to_port[key.flow_id] = port_no;
1357 }
1358 bcmos_fastlock_unlock(&data_lock, 0);
1359 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001360 if (gemport_id >= 0 && access_intf_id >= 0) {
1361 // Update the flow_to_acl_map. Note that since this is a datapath flow, acl_id is -1
1362 // This info is needed during flow remove where we need to retrieve the gemport_id
1363 // and access_intf id for the given flow id and flow direction.
1364 // After retrieving the ACL ID and GEM PORT ID, we decrement the corresponding
1365 // reference counters for those ACL ID and GEMPORT ID.
1366 acl_id_gem_id_intf_id ac_id_gm_id_if_id(-1, gemport_id, access_intf_id);
1367 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
1368 bcmos_fastlock_lock(&data_lock);
1369 flow_to_acl_map[fl_id_fl_dir] = ac_id_gm_id_if_id;
1370 bcmos_fastlock_unlock(&data_lock, 0);
1371 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001372 if (priority_value >= 0) {
1373 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
1374 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301375
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001376 } else { // MULTICAST FLOW
1377 if (group_id >= 0) {
1378 BCMOLT_MSG_FIELD_SET(&cfg, group_id, group_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001379 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001380 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1381 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001382 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001383
1384 {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001385 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001386 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001387 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
1388 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001389 }
1390
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001391 if (classifier.dst_mac().size() > 0) {
1392 bcmos_mac_address d_mac = {};
1393 bcmos_mac_address_init(&d_mac);
1394 memcpy(d_mac.u8, classifier.dst_mac().data(), sizeof(d_mac.u8));
1395 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_mac %02x:%02x:%02x:%02x:%02x:%02x\n", d_mac.u8[0],
1396 d_mac.u8[1], d_mac.u8[2], d_mac.u8[3], d_mac.u8[4], d_mac.u8[5]);
1397 BCMOLT_FIELD_SET(&c_val, classifier, dst_mac, d_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001398 }
1399
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001400 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001401 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001402 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001403 }
1404 */
1405
1406 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001407 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
1408 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001409 }
1410
1411 /*
1412 if (classifier.dst_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001413 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_ip, classifier.dst_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001414 }
1415
1416 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001417 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001418 }
1419 */
1420
1421 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001422 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
1423 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001424 }
1425
1426 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001427 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
1428 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001429 }
1430
1431 if (!classifier.pkt_tag_type().empty()) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001432 if (classifier.o_vid()) {
1433 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
1434 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
1435 }
1436
1437 if (classifier.i_vid()) {
1438 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
1439 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
1440 }
1441
1442 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
1443 if (classifier.pkt_tag_type().compare("untagged") == 0) {
1444 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
1445 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
1446 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
1447 single_tag = true;
1448
1449 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301450 // OpenOlt adapter will send 0xFF in case of no pbit classification
1451 // If it is any other value (0 to 7), it is for outer pbit classification.
1452 // OpenFlow protocol does not provide inner pbit classification (in case of double tagged packets),
1453 // and VOLTHA has not used any workaround to solve this problem (for ex: use metadata field).
1454 // Also there exists no use case for i-pbit classification, so we can safely ignore this for now.
1455 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001456 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301457 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001458 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
1459 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001460
Jason Huang09b73ea2020-01-08 17:52:05 +08001461 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301462 // Same comments as in case of "single_tag" packets.
1463 // 0xFF means no pbit classification, otherwise a valid PCP (0 to 7).
1464 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001465 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301466 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001467 }
1468 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001469 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001470 }
1471
Jason Huang09b73ea2020-01-08 17:52:05 +08001472 const ::openolt::ActionCmd& cmd = action.cmd();
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001473
Jason Huang09b73ea2020-01-08 17:52:05 +08001474 if (cmd.add_outer_tag()) {
1475 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
1476 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001477 }
1478
Jason Huang09b73ea2020-01-08 17:52:05 +08001479 if (cmd.remove_outer_tag()) {
1480 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
1481 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
1482 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301483
Jason Huang09b73ea2020-01-08 17:52:05 +08001484 if (action.o_vid()) {
1485 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
1486 o_vid = action.o_vid();
1487 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
1488 }
1489
1490 if (action.o_pbits()) {
1491 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
1492 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
1493 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301494
Jason Huang09b73ea2020-01-08 17:52:05 +08001495 if (action.i_vid()) {
1496 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
1497 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
1498 }
1499
1500 if (action.i_pbits()) {
1501 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
1502 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
1503 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301504
Jason Huang09b73ea2020-01-08 17:52:05 +08001505 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
1506
Shad Ansari39739bc2018-09-13 21:38:37 +00001507 if ((access_intf_id >= 0) && (onu_id >= 0)) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001508 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
1509 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
1510 tm_val.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, downstream);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001511
Jason Huang09b73ea2020-01-08 17:52:05 +08001512 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1513 // Queue 0 on DS subscriber scheduler
1514 tm_val.queue_id = 0;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001515
Jason Huang09b73ea2020-01-08 17:52:05 +08001516 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1517 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1518 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001519
Jason Huang09b73ea2020-01-08 17:52:05 +08001520 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1521 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1522 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001523
Jason Huang09b73ea2020-01-08 17:52:05 +08001524 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1525 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
1526 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 +00001527
Jason Huang09b73ea2020-01-08 17:52:05 +08001528 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1529 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1530 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1531 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 +00001532
Jason Huang09b73ea2020-01-08 17:52:05 +08001533 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
1534 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1535 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1536 }
1537 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
1538 // NNI Scheduler ID
1539 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1540 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1541 // Queue 0 on NNI scheduler
1542 tm_val.queue_id = 0;
1543 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1544 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1545 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001546
Jason Huang09b73ea2020-01-08 17:52:05 +08001547 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 +00001548 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1549 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1550
Jason Huang09b73ea2020-01-08 17:52:05 +08001551 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1552 /* Fetch TM QMP ID mapped to US NNI scheduler */
1553 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
1554 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1555 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1556 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1557 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 +00001558
Jason Huang09b73ea2020-01-08 17:52:05 +08001559 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 +00001560 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1561 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001562 }
Shad Ansari39739bc2018-09-13 21:38:37 +00001563 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301564 } else {
1565 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1566 tm_val.queue_id = 0;
1567
1568 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
1569 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1570 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
1571
1572 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1573 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
1574 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00001575 }
1576
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001577 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001578
1579 // BAL 3.1 supports statistics only for unicast flows.
1580 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1581 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
1582 }
1583
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001584#ifdef FLOW_CHECKER
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001585 //Flow Checker, To avoid duplicate flow.
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001586 if (flow_id_counters != 0) {
1587 bool b_duplicate_flow = false;
Jason Huang09b73ea2020-01-08 17:52:05 +08001588 std::map<flow_pair, int>::iterator it;
1589
1590 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1591 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(it->first.first, it->first.second, ONU_ID)) && \
1592 (key.flow_type == it->first.second) && \
1593 (cfg.data.svc_port_id == get_flow_status(it->first.first, it->first.second, SVC_PORT_ID)) && \
1594 (cfg.data.priority == get_flow_status(it->first.first, it->first.second, PRIORITY)) && \
1595 (cfg.data.cookie == get_flow_status(it->first.first, it->first.second, COOKIE)) && \
1596 (cfg.data.ingress_intf.intf_type == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_TYPE)) && \
1597 (cfg.data.ingress_intf.intf_id == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_ID)) && \
1598 (cfg.data.egress_intf.intf_type == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_TYPE)) && \
1599 (cfg.data.egress_intf.intf_id == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_ID)) && \
1600 (c_val.o_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_VID)) && \
1601 (c_val.o_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_PBITS)) && \
1602 (c_val.i_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_VID)) && \
1603 (c_val.i_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_PBITS)) && \
1604 (c_val.ether_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_ETHER_TYPE)) && \
1605 (c_val.ip_proto == get_flow_status(it->first.first, it->first.second, CLASSIFIER_IP_PROTO)) && \
1606 (c_val.src_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_SRC_PORT)) && \
1607 (c_val.dst_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_DST_PORT)) && \
1608 (c_val.pkt_tag_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_PKT_TAG_TYPE)) && \
1609 (cfg.data.egress_qos.type == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TYPE)) && \
1610 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_QUEUE_ID)) && \
1611 (cfg.data.egress_qos.tm_sched.id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TM_SCHED_ID)) && \
1612 (a_val.cmds_bitmask == get_flow_status(it->first.first, it->first.second, ACTION_CMDS_BITMASK)) && \
1613 (a_val.o_vid == get_flow_status(it->first.first, it->first.second, ACTION_O_VID)) && \
1614 (a_val.i_vid == get_flow_status(it->first.first, it->first.second, ACTION_I_VID)) && \
1615 (a_val.o_pbits == get_flow_status(it->first.first, it->first.second, ACTION_O_PBITS)) && \
1616 (a_val.i_pbits == get_flow_status(it->first.first, it->first.second, ACTION_I_PBITS)) && \
1617 (cfg.data.state == get_flow_status(it->first.first, it->first.second, STATE)) && \
1618 (cfg.data.group_id == get_flow_status(it->first.first, it->first.second, GROUP_ID));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001619#ifdef SHOW_FLOW_PARAM
1620 // Flow Parameter
1621 FLOW_PARAM_LOG();
1622#endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001623 if (b_duplicate_flow) {
1624 FLOW_LOG(WARNING, "Flow duplicate", 0);
1625 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
1626 }
1627 }
1628 }
1629#endif
1630
1631 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
1632 if (err) {
1633 FLOW_LOG(ERROR, "Flow add failed", err);
1634 return bcm_to_grpc_err(err, "flow add failed");
1635 } else {
1636 FLOW_LOG(INFO, "Flow add ok", err);
1637 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08001638 flow_map[std::pair<int, int>(key.flow_id,key.flow_type)] = flow_map.size();
1639 flow_id_counters = flow_map.size();
1640 if (gemport_id > 0 && access_intf_id >= 0) {
1641 gem_id_intf_id gem_intf(gemport_id, access_intf_id);
1642 if (gem_ref_cnt.count(gem_intf) > 0) {
1643 // The gem port is already installed
1644 // Increment the ref counter indicating number of flows referencing this gem port
1645 gem_ref_cnt[gem_intf]++;
1646 OPENOLT_LOG(DEBUG, openolt_log_id, "incremented gem_ref_cnt, gem_ref_cnt=%d\n", gem_ref_cnt[gem_intf]);
1647 } else {
1648 // Initialize the refence count for the gemport.
1649 gem_ref_cnt[gem_intf] = 1;
1650 OPENOLT_LOG(DEBUG, openolt_log_id, "initialized gem_ref_cnt\n");
1651 }
1652 } else {
1653 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);
1654 }
1655
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001656 bcmos_fastlock_unlock(&data_lock, 0);
1657 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04001658
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001659 return Status::OK;
1660}
1661
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001662Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
1663
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001664 bcmolt_flow_cfg cfg;
1665 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001666
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001667 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001668 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001669 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001670 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001671 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001672 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001673 } else if(flow_type.compare(multicast) == 0) {
1674 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001675 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001676 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001677 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
1678 }
1679
Jason Huang09b73ea2020-01-08 17:52:05 +08001680 OPENOLT_LOG(INFO, openolt_log_id, "flow remove received for flow_id=%u, flow_type=%s\n",
1681 flow_id, flow_type.c_str());
1682
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001683 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08001684 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
1685 int32_t gemport_id = -1;
1686 int32_t intf_id = -1;
1687 int16_t acl_id = -1;
1688 if (flow_to_acl_map.count(fl_id_fl_dir) > 0) {
1689 acl_id_gem_id_intf_id ac_id_gm_id_if_id = flow_to_acl_map[fl_id_fl_dir];
1690 acl_id = std::get<0>(ac_id_gm_id_if_id);
1691 gemport_id = std::get<1>(ac_id_gm_id_if_id);
1692 intf_id = std::get<2>(ac_id_gm_id_if_id);
1693 // cleanup acl only if it is a valid acl. If not valid acl, it may be datapath flow.
1694 if (acl_id >= 0) {
1695 Status resp = handle_acl_rule_cleanup(acl_id, gemport_id, intf_id, flow_type);
1696 bcmos_fastlock_unlock(&data_lock, 0);
1697 if (resp.ok()) {
1698 OPENOLT_LOG(INFO, openolt_log_id, "acl removed ok for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
1699 flow_to_acl_map.erase(fl_id_fl_dir);
1700 } else {
1701 OPENOLT_LOG(ERROR, openolt_log_id, "acl remove error for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
1702 }
1703 return resp;
1704 }
1705 }
1706
Craig Lutgen967a1d02018-11-27 10:41:51 -06001707 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001708 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06001709 flowid_to_gemport.erase(key.flow_id);
1710 port_to_flows[port_no].erase(key.flow_id);
1711 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
1712 }
1713 else
1714 {
1715 flowid_to_port.erase(key.flow_id);
1716 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001717 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001718
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001719 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001720
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001721 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001722 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001723 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 -04001724 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
1725 }
1726
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001727 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08001728 if (flow_id_counters != 0) {
1729 std::map<flow_pair, int>::iterator it;
1730 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1731 if (it->first.first == flow_id && it->first.second == key.flow_type) {
1732 flow_id_counters -= 1;
1733 flow_map.erase(it);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001734 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001735 }
1736 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001737 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
1738
1739 clear_gem_port(gemport_id, intf_id);
1740
1741 flow_to_acl_map.erase(fl_id_fl_dir);
1742
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001743 bcmos_fastlock_unlock(&data_lock, 0);
1744
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001745 return Status::OK;
1746}
1747
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001748bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
1749 bcmos_errno err;
1750 bcmolt_tm_sched_cfg tm_sched_cfg;
1751 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
1752 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
1753
Jason Huangbf45ffb2019-10-30 17:29:02 +08001754 //check TM scheduler has configured or not
1755 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
1756 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001757 #ifdef TEST_MODE
1758 // It is impossible to mock the setting of tm_sched_cfg.data.state because
1759 // the actual bcmolt_cfg_get passes the address of tm_sched_cfg.hdr and we cannot
1760 // set the tm_sched_cfg.data.state. So a new stub function is created and address
1761 // of tm_sched_cfg is passed. This is one-of case where we need to add test specific
1762 // code in production code.
1763 err = bcmolt_cfg_get__tm_sched_stub(dev_id, &tm_sched_cfg);
1764 #else
Jason Huangbf45ffb2019-10-30 17:29:02 +08001765 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001766 #endif
Jason Huangbf45ffb2019-10-30 17:29:02 +08001767 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001768 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 +08001769 return err;
1770 }
1771 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
1772 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
1773 return BCM_ERR_OK;
1774 }
1775
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001776 // bcmbal_tm_sched_owner
1777 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
1778
1779 /**< The output of the tm_sched object instance */
1780 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
1781
1782 if (direction.compare(upstream) == 0) {
1783 // In upstream it is NNI scheduler
1784 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
1785 } else if (direction.compare(downstream) == 0) {
1786 // In downstream it is PON scheduler
1787 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
1788 }
1789
1790 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
1791
1792 // bcmbal_tm_sched_type
1793 // set the deafult policy to strict priority
1794 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
1795
1796 // num_priorities: Max number of strict priority scheduling elements
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001797 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, NUM_OF_PRIORITIES);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001798
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001799 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
1800 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001801 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
1802 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001803 return err;
1804 }
1805
1806 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
1807 direction.c_str(), tm_sched_key.id, intf_id);
1808 return BCM_ERR_OK;
1809}
1810
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001811bcmos_errno CreateSched(std::string direction, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t port_no,
1812 uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
1813 tech_profile::SchedulingPolicy sched_policy, tech_profile::TrafficShapingInfo tf_sh_info) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001814
1815 bcmos_errno err;
1816
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001817 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001818 bcmolt_tm_sched_cfg tm_sched_cfg;
1819 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
1820 tm_sched_key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001821
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001822 // bcmbal_tm_sched_owner
1823 // In downstream it is sub_term scheduler
1824 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001825
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001826 /**< The output of the tm_sched object instance */
1827 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001828
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001829 // bcmbal_tm_sched_parent
1830 // The parent for the sub_term scheduler is the PON scheduler in the downstream
1831 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
1832 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 +00001833 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001834 be achieved using the' virtual' type of attachment.
1835 tm_sched_owner.u.sub_term.intf_id = intf_id;
1836 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
1837 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001838
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001839 // bcmbal_tm_sched_type
1840 // set the deafult policy to strict priority
1841 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001842
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001843 // num_priorities: Max number of strict priority scheduling elements
1844 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001845
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001846 // bcmbal_tm_shaping
1847 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
1848 uint32_t cir = tf_sh_info.cir();
1849 uint32_t pir = tf_sh_info.pir();
1850 uint32_t burst = tf_sh_info.pbs();
1851 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
1852 cir, pir, burst);
1853 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
1854 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
1855 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
1856 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
1857 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
1858 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001859 }
1860
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001861 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001862 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001863 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001864intf_id %d, onu_id %d, uni_id %d, port_no %u, err = %s\n", tm_sched_key.id, intf_id, onu_id, uni_id, \
1865port_no, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001866 return err;
1867 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001868 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
1869uni_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 -08001870
1871 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001872 bcmolt_itupon_alloc_cfg cfg;
1873 bcmolt_itupon_alloc_key key = { };
1874 key.pon_ni = intf_id;
1875 key.alloc_id = alloc_id;
1876 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
Burak Gurdag03919c72020-02-04 22:46:57 +00001877 int pir_bw = tf_sh_info.pir()*125; // conversion from kbps to bytes/sec
1878 int cir_bw = tf_sh_info.cir()*125; // conversion from kbps to bytes/sec
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001879 //offset to match bandwidth granularity
1880 int offset_pir_bw = pir_bw%bw_granularity;
1881 int offset_cir_bw = cir_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001882
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001883 pir_bw = pir_bw - offset_pir_bw;
1884 cir_bw = cir_bw - offset_cir_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001885
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001886 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001887
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001888 switch (additional_bw) {
1889 case 2: //AdditionalBW_BestEffort
1890 if (pir_bw == 0) {
1891 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
1892%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001893 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001894 } else if (pir_bw < cir_bw) {
1895 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
1896bandwidth (%d)\n", pir_bw, cir_bw);
1897 return BCM_ERR_PARM;
1898 } else if (pir_bw == cir_bw) {
1899 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
1900bandwidth for additional bandwidth eligibility of type best_effort\n");
1901 return BCM_ERR_PARM;
1902 }
1903 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
1904 break;
1905 case 1: //AdditionalBW_NA
1906 if (pir_bw == 0) {
1907 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
1908%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
1909 return BCM_ERR_PARM;
1910 } else if (cir_bw == 0) {
1911 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
1912additional bandwidth eligibility of type Non-Assured (NA)\n");
1913 return BCM_ERR_PARM;
1914 } else if (pir_bw < cir_bw) {
1915 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
1916bandwidth (%d)\n", pir_bw, cir_bw);
1917 return BCM_ERR_PARM;
1918 } else if (pir_bw == cir_bw) {
1919 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
1920bandwidth for additional bandwidth eligibility of type non_assured\n");
1921 return BCM_ERR_PARM;
1922 }
1923 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
1924 break;
1925 case 0: //AdditionalBW_None
1926 if (pir_bw == 0) {
1927 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
192816000 bytes/sec\n");
1929 return BCM_ERR_PARM;
1930 } else if (cir_bw == 0) {
1931 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
1932for additional bandwidth eligibility of type None\n");
1933 return BCM_ERR_PARM;
1934 } else if (pir_bw > cir_bw) {
1935 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
1936for additional bandwidth eligibility of type None\n");
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001937 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001938bandwidth in None eligibility\n", pir_bw);
1939 cir_bw = pir_bw;
1940 } else if (pir_bw < cir_bw) {
1941 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
1942bandwidth (%d)\n", pir_bw, cir_bw);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001943 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001944bandwidth in None eligibility\n", pir_bw);
1945 cir_bw = pir_bw;
1946 }
1947 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
1948 break;
1949 default:
1950 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08001951 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001952 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
1953 in a fine granularity. */
1954 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
1955 /* Fixed Bandwidth with no critical requirement of shaping */
1956 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, 0);
1957 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
1958 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, cir_bw);
1959 /* Maximum allocated bandwidth allowed for this alloc ID */
1960 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
1961 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001962 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001963 for skipped allocations during quiet window */
1964 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
1965 /**< Allocation Profile index for CBR non-RT Bandwidth */
1966 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
1967 /**< Allocation Profile index for CBR RT Bandwidth */
1968 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
1969 /**< Alloc ID Weight used in case of Extended DBA mode */
1970 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
1971 /**< Alloc ID Priority used in case of Extended DBA mode */
1972 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
1973 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001974
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001975 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001976 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001977 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 -05001978port_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 -08001979 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001980 }
Girish Gowdra96461052019-11-22 20:13:59 +05301981
1982 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
1983 if (err) {
1984 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
1985port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
1986 return err;
1987 }
1988
1989 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
1990port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
1991
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001992 }
1993
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001994 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001995}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001996
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001997Status CreateTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
1998 uint32_t intf_id = traffic_scheds->intf_id();
1999 uint32_t onu_id = traffic_scheds->onu_id();
2000 uint32_t uni_id = traffic_scheds->uni_id();
2001 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002002 std::string direction;
2003 unsigned int alloc_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002004 tech_profile::SchedulerConfig sched_config;
2005 tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002006 uint32_t priority;
2007 uint32_t weight;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002008 tech_profile::SchedulingPolicy sched_policy;
2009 tech_profile::TrafficShapingInfo traffic_shaping_info;
2010 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002011
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002012 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2013 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002014
2015 direction = GetDirection(traffic_sched.direction());
2016 if (direction.compare("direction-not-supported") == 0)
2017 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2018
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002019 alloc_id = traffic_sched.alloc_id();
2020 sched_config = traffic_sched.scheduler();
2021 additional_bw = sched_config.additional_bw();
2022 priority = sched_config.priority();
2023 weight = sched_config.weight();
2024 sched_policy = sched_config.sched_policy();
2025 traffic_shaping_info = traffic_sched.traffic_shaping_info();
2026 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
2027 sched_policy, traffic_shaping_info);
2028 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002029 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002030 return bcm_to_grpc_err(err, "Failed to create scheduler");
2031 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002032 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002033 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002034}
Jonathan Davis70c21812018-07-19 15:32:10 -04002035
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002036bcmos_errno RemoveSched(int intf_id, int onu_id, int uni_id, int alloc_id, std::string direction) {
Jonathan Davis70c21812018-07-19 15:32:10 -04002037
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002038 bcmos_errno err;
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302039 bcmolt_interface_state state;
Girish Gowdra96461052019-11-22 20:13:59 +05302040 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002041
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002042 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002043 bcmolt_itupon_alloc_cfg cfg;
2044 bcmolt_itupon_alloc_key key = { };
2045 key.pon_ni = intf_id;
2046 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302047 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002048
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002049 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002050 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2051 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002052 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2053 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002054 return err;
2055 }
Girish Gowdra96461052019-11-22 20:13:59 +05302056
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302057 err = get_pon_interface_status((bcmolt_interface)intf_id, &state);
2058 if (err == BCM_ERR_OK) {
2059 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
2060 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is enabled, waiting for alloc cfg clear response\n",
2061 intf_id);
2062 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2063 if (err) {
2064 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2065 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
2066 return err;
2067 }
2068 }
2069 else if (state == BCMOLT_INTERFACE_STATE_INACTIVE) {
2070 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is disabled, not waiting for alloc cfg clear response\n",
2071 intf_id);
2072 }
2073 }
2074 else {
2075 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch PON interface state, intf_id = %d, err = %s\n",
2076 intf_id, bcmos_strerror(err));
Girish Gowdra96461052019-11-22 20:13:59 +05302077 return err;
2078 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002079 } else if (direction == downstream) {
2080 bcmolt_tm_sched_cfg cfg;
2081 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002082
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002083 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction)) {
2084 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
Girish Gowdra96461052019-11-22 20:13:59 +05302085 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002086 } else {
2087 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2088 return BCM_ERR_OK;
2089 }
Girish Gowdra96461052019-11-22 20:13:59 +05302090
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002091 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2092 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2093 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002094 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
2095intf_id %d, onu_id %d, err = %s\n", direction.c_str(), key.id, intf_id, onu_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002096 return err;
2097 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002098 }
2099
Girish Gowdra96461052019-11-22 20:13:59 +05302100 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d\n",
2101 direction.c_str(), sched_id, intf_id, onu_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002102 free_tm_sched_id(intf_id, onu_id, uni_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002103 return BCM_ERR_OK;
2104}
2105
2106Status RemoveTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2107 uint32_t intf_id = traffic_scheds->intf_id();
2108 uint32_t onu_id = traffic_scheds->onu_id();
2109 uint32_t uni_id = traffic_scheds->uni_id();
2110 std::string direction;
2111 bcmos_errno err;
2112
2113 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2114 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002115
2116 direction = GetDirection(traffic_sched.direction());
2117 if (direction.compare("direction-not-supported") == 0)
2118 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2119
2120 int alloc_id = traffic_sched.alloc_id();
2121 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002122 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002123 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002124 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2125 }
2126 }
2127 return Status::OK;
2128}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002129
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002130bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2131 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002132 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002133 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2134 bcmolt_tm_qmp_key tm_qmp_key;
2135 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002136
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002137 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2138 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002139 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed tm queue mapping profile count is 16.\n");
2140 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002141 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002142
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002143 tm_qmp_key.id = tm_qmp_id;
2144 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2145 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2146 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002147
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002148 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2149 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2150 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002151 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2152 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002153
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002154 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002155 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002156 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2157 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002158 return err;
2159 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002160
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002161 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2162 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002163 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002164}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002165
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002166bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2167 bcmos_errno err;
2168 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2169 bcmolt_tm_qmp_key tm_qmp_key;
2170 tm_qmp_key.id = tm_qmp_id;
2171
2172 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2173 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2174 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002175 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2176 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002177 return err;
2178 }
2179
2180 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2181 tm_qmp_key.id);
2182 return BCM_ERR_OK;
2183}
2184
2185bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2186 bcmos_errno err;
2187
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002188 /* Create default queues on the given PON/NNI scheduler */
2189 for (int queue_id = 0; queue_id < NUMBER_OF_DEFAULT_INTERFACE_QUEUES; queue_id++) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002190 bcmolt_tm_queue_cfg tm_queue_cfg;
2191 bcmolt_tm_queue_key tm_queue_key = {};
2192 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2193 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002194 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2195 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2196 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002197
2198 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2199 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2200 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2201
2202 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2203 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002204 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", \
2205 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 +00002206 return err;
2207 }
2208
2209 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2210 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2211 }
2212 return BCM_ERR_OK;
2213}
2214
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002215bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
2216 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002217 bcmos_errno err;
2218 bcmolt_tm_queue_cfg cfg;
2219 bcmolt_tm_queue_key key = { };
2220 OPENOLT_LOG(INFO, openolt_log_id, "creating %s queue. access_intf_id = %d, onu_id = %d, uni_id = %d \
2221gemport_id = %d\n", direction.c_str(), access_intf_id, onu_id, uni_id, gemport_id);
2222
2223 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2224 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
2225
2226 if (priority > 7) {
2227 return BCM_ERR_RANGE;
2228 }
2229
2230 /* FIXME: The upstream queues have to be created once only.
2231 The upstream queues on the NNI scheduler are shared by all subscribers.
2232 When the first scheduler comes in, the queues get created, and are re-used by all others.
2233 Also, these queues should be present until the last subscriber exits the system.
2234 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2235
2236 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2237 for each GEM in TECH PROFILE */
2238 key.id = queue_id_list[priority];
2239
2240 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2241 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2242 key.id = 0;
2243 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2244 }
2245 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2246 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2247 }
2248 else {
2249 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2250 }
2251
2252 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2253
2254 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2255 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
2256
2257 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2258 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002259 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
2260sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n", \
2261 direction.c_str(), key.id, key.sched_id, key.tm_q_set_id, access_intf_id, onu_id, uni_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002262 return err;
2263 }
2264
2265 OPENOLT_LOG(INFO, openolt_log_id, "Created tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2266intf_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);
2267 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002268}
2269
2270Status CreateTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2271 uint32_t intf_id = traffic_queues->intf_id();
2272 uint32_t onu_id = traffic_queues->onu_id();
2273 uint32_t uni_id = traffic_queues->uni_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002274 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002275 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002276 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002277 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 +00002278
2279 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2280 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2281 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2282 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2283 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
2284
2285 direction = GetDirection(traffic_queue.direction());
2286 if (direction.compare("direction-not-supported") == 0)
2287 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2288
2289 queues_priority_q[i] = traffic_queue.priority();
2290 queues_pbit_map[i] = traffic_queue.pbit_map();
2291 }
2292
2293 std::vector<uint32_t> tmq_map_profile(8, 0);
2294 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2295 queues_priority_q, COUNT_OF(queues_priority_q));
2296 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2297 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
2298
2299 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2300 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002301 err = CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2302 if (err != BCM_ERR_OK) {
2303 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2304 return bcm_to_grpc_err(err, "Failed to create tm queue mapping profile");
2305 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002306 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2307 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2308 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2309 }
2310 }
2311
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002312 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2313 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002314
2315 direction = GetDirection(traffic_queue.direction());
2316 if (direction.compare("direction-not-supported") == 0)
2317 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2318
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002319 err = CreateQueue(direction, intf_id, onu_id, uni_id, qos_type, traffic_queue.priority(), traffic_queue.gemport_id());
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002320
Girish Gowdruf26cf882019-05-01 23:47:58 -07002321 // If the queue exists already, lets not return failure and break the loop.
2322 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002323 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002324 return bcm_to_grpc_err(err, "Failed to create queue");
2325 }
2326 }
2327 return Status::OK;
2328}
2329
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002330bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
2331 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002332 bcmolt_tm_queue_cfg cfg;
2333 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002334 bcmos_errno err;
2335
2336 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002337 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction)) {
2338 key.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
2339 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002340 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002341 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 -08002342 return BCM_ERR_OK;
2343 }
2344 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002345 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2346 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002347 return BCM_ERR_OK;
2348 }
2349
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002350 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2351 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2352 // Reset the queue id to 0 when using fixed queue.
2353 key.id = 0;
2354 }
2355 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2356 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2357 }
2358 else {
2359 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2360 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002361
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002362 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2363 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002364 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002365 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, queue_id %d, sched_id %d, \
2366tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n",
2367 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 -08002368 return err;
2369 }
2370
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002371 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2372intf_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 -08002373
2374 return BCM_ERR_OK;
2375}
2376
2377Status RemoveTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2378 uint32_t intf_id = traffic_queues->intf_id();
2379 uint32_t onu_id = traffic_queues->onu_id();
2380 uint32_t uni_id = traffic_queues->uni_id();
2381 uint32_t port_no = traffic_queues->port_no();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002382 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002383 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002384 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002385 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 +00002386
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002387 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2388 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002389
2390 direction = GetDirection(traffic_queue.direction());
2391 if (direction.compare("direction-not-supported") == 0)
2392 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2393
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002394 err = RemoveQueue(direction, intf_id, onu_id, uni_id, qos_type, traffic_queue.priority(), traffic_queue.gemport_id());
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002395 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002396 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002397 return bcm_to_grpc_err(err, "Failed to remove queue");
2398 }
Jonathan Davis70c21812018-07-19 15:32:10 -04002399 }
2400
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002401 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))) {
2402 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2403 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
2404
2405 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
2406 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002407 err = RemoveTrafficQueueMappingProfile(tm_qmp_id);
2408 if (err != BCM_ERR_OK) {
2409 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2410 return bcm_to_grpc_err(err, "Failed to remove tm queue mapping profile");
2411 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002412 }
2413 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002414 clear_qos_type(intf_id, onu_id, uni_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04002415 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04002416}
Jason Huangbf45ffb2019-10-30 17:29:02 +08002417
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002418Status PerformGroupOperation_(const openolt::Group *group_cfg) {
2419
2420 bcmos_errno err;
2421 bcmolt_group_key key = {};
2422 bcmolt_group_cfg grp_cfg_obj;
2423 bcmolt_group_members_update grp_mem_upd;
2424 bcmolt_members_update_command grp_mem_upd_cmd;
2425 bcmolt_group_member_info member_info = {};
2426 bcmolt_group_member_info_list_u8 members = {};
2427 bcmolt_intf_ref interface_ref = {};
2428 bcmolt_egress_qos egress_qos = {};
2429 bcmolt_tm_sched_ref tm_sched_ref = {};
2430 bcmolt_action a_val = {};
2431
2432 uint32_t group_id = group_cfg->group_id();
2433
2434 OPENOLT_LOG(INFO, openolt_log_id, "PerformGroupOperation request received for Group %d\n", group_id);
2435
2436 if (group_id >= 0) {
2437 key.id = group_id;
2438 }
2439 else {
2440 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
2441 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
2442 }
2443
2444 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2445 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
2446
2447 OPENOLT_LOG(INFO, openolt_log_id, "Checking if Group %d exists...\n",group_id);
2448
2449 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
2450 if (err != BCM_ERR_OK) {
2451 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
2452 return bcm_to_grpc_err(err, "Error in querying group");
2453 }
2454
2455 members.len = group_cfg->members_size();
2456
2457 // IMPORTANT: A member cannot be added to a group if the group type is not determined.
2458 // Group type is determined after a flow is assigned to it.
2459 // Therefore, a group must be created first, then a flow (with multicast type) must be assigned to it.
2460 // Only then we can add members to the group.
2461
2462 // if group does not exist, create it and return.
2463 if (grp_cfg_obj.data.state == BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
2464
2465 if (members.len != 0) {
2466 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);
2467 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Non-empty member list given for non-existent group");
2468 } else {
2469
2470 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2471 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, cookie, key.id);
2472
2473 /* Setting group actions and action parameters, if any.
2474 Only remove_outer_tag and translate_inner_tag actions and i_vid action parameter
2475 are supported for multicast groups in BAL 3.1.
2476 */
2477 const ::openolt::Action& action = group_cfg->action();
2478 const ::openolt::ActionCmd &cmd = action.cmd();
2479
2480 bcmolt_action_cmd_id cmd_bmask = BCMOLT_ACTION_CMD_ID_NONE;
2481 if (cmd.remove_outer_tag()) {
2482 OPENOLT_LOG(INFO, openolt_log_id, "Action remove_outer_tag applied to Group %d.\n", group_id);
2483 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
2484 }
2485
2486 if (cmd.translate_inner_tag()) {
2487 OPENOLT_LOG(INFO, openolt_log_id, "Action translate_inner_tag applied to Group %d.\n", group_id);
2488 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG);
2489 }
2490
2491 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, cmd_bmask);
2492
2493 if (action.i_vid()) {
2494 OPENOLT_LOG(INFO, openolt_log_id, "Setting action parameter i_vid=%d for Group %d.\n", action.i_vid(), group_id);
2495 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
2496 }
2497
2498 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, action, a_val);
2499
2500 // Create group
2501 err = bcmolt_cfg_set(dev_id, &(grp_cfg_obj.hdr));
2502
2503 if (BCM_ERR_OK != err) {
2504 BCM_LOG(ERROR, openolt_log_id, "Failed to create Group %d, err = %s (%d)\n", key.id, bcmos_strerror(err), err);
2505 return bcm_to_grpc_err(err, "Error in creating group");
2506 }
2507
2508 BCM_LOG(INFO, openolt_log_id, "Group %d has been created and configured with empty member list.\n", key.id);
2509 return Status::OK;
2510 }
2511 }
2512
2513 // The group already exists. Continue configuring it according to the update member command.
2514
2515 OPENOLT_LOG(INFO, openolt_log_id, "Configuring existing Group %d.\n",group_id);
2516
2517 // MEMBER LIST CONSTRUCTION
2518 // Note that members.len can be 0 here. if the group already exists and the command is SET then sending
2519 // empty list to the group is a legit operation and this actually empties the member list.
2520 members.arr = (bcmolt_group_member_info*)bcmos_calloc((members.len)*sizeof(bcmolt_group_member_info));
2521
2522 if (!members.arr) {
2523 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to allocate memory for group member list.\n");
2524 return grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "Memory exhausted during member list creation");
2525 }
2526
2527 /* SET GROUP MEMBERS UPDATE COMMAND */
2528 openolt::Group::GroupMembersCommand command = group_cfg->command();
2529 switch(command) {
2530 case openolt::Group::SET_MEMBERS :
2531 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_SET;
2532 OPENOLT_LOG(INFO, openolt_log_id, "Setting %d members for Group %d.\n", members.len, group_id);
2533 break;
2534 case openolt::Group::ADD_MEMBERS :
2535 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_ADD;
2536 OPENOLT_LOG(INFO, openolt_log_id, "Adding %d members to Group %d.\n", members.len, group_id);
2537 break;
2538 case openolt::Group::REMOVE_MEMBERS :
2539 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_REMOVE;
2540 OPENOLT_LOG(INFO, openolt_log_id, "Removing %d members from Group %d.\n", members.len, group_id);
2541 break;
2542 default :
2543 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid value %d for group member command.\n", command);
2544 bcmos_free(members.arr);
2545 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group member command");
2546 }
2547
2548 // SET MEMBERS LIST
2549 for (int i = 0; i < members.len; i++) {
2550
2551 if (command == openolt::Group::REMOVE_MEMBERS) {
2552 OPENOLT_LOG(INFO, openolt_log_id, "Removing group member %d from group %d\n",i,key.id);
2553 } else {
2554 OPENOLT_LOG(INFO, openolt_log_id, "Adding group member %d to group %d\n",i,key.id);
2555 }
2556
2557 openolt::GroupMember *member = (openolt::GroupMember *) &group_cfg->members()[i];
2558
2559 // Set member interface type
2560 openolt::GroupMember::InterfaceType if_type = member->interface_type();
2561 switch(if_type){
2562 case openolt::GroupMember::PON :
2563 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_PON);
2564 OPENOLT_LOG(INFO, openolt_log_id, "Interface type PON is assigned to GroupMember %d\n",i);
2565 break;
2566 case openolt::GroupMember::EPON_1G_PATH :
2567 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_1_G);
2568 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_1G is assigned to GroupMember %d\n",i);
2569 break;
2570 case openolt::GroupMember::EPON_10G_PATH :
2571 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_10_G);
2572 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_10G is assigned to GroupMember %d\n",i);
2573 break;
2574 default :
2575 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid interface type value %d for GroupMember %d.\n",if_type,i);
2576 bcmos_free(members.arr);
2577 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface type for a group member");
2578 }
2579
2580 // Set member interface id
2581 if (member->interface_id() >= 0) {
2582 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_id, member->interface_id());
2583 OPENOLT_LOG(INFO, openolt_log_id, "Interface %d is assigned to GroupMember %d\n", member->interface_id(), i);
2584 } else {
2585 bcmos_free(members.arr);
2586 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface id for a group member");
2587 }
2588
2589 // Set member interface_ref
2590 BCMOLT_FIELD_SET(&member_info, group_member_info, intf, interface_ref);
2591
2592 // Set member gem_port_id. This must be a multicast gemport.
2593 if (member->gem_port_id() >= 0) {
2594 BCMOLT_FIELD_SET(&member_info, group_member_info, svc_port_id, member->gem_port_id());
2595 OPENOLT_LOG(INFO, openolt_log_id, "GEM Port %d is assigned to GroupMember %d\n", member->gem_port_id(), i);
2596 } else {
2597 bcmos_free(members.arr);
2598 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid gem port id for a group member");
2599 }
2600
2601 // Set member scheduler id and queue_id
2602 uint32_t tm_sched_id = get_default_tm_sched_id(member->interface_id(), downstream);
2603 OPENOLT_LOG(INFO, openolt_log_id, "Scheduler %d is assigned to GroupMember %d\n", tm_sched_id, i);
2604 BCMOLT_FIELD_SET(&tm_sched_ref, tm_sched_ref, id, tm_sched_id);
2605 BCMOLT_FIELD_SET(&egress_qos, egress_qos, tm_sched, tm_sched_ref);
2606
2607 // We assume that all multicast traffic destined to a PON port is using the same fixed queue.
2608 uint32_t tm_queue_id;
2609 if (member->priority() >= 0 && member->priority() < NUMBER_OF_DEFAULT_INTERFACE_QUEUES) {
2610 tm_queue_id = queue_id_list[member->priority()];
2611 OPENOLT_LOG(INFO, openolt_log_id, "Queue %d is assigned to GroupMember %d\n", tm_queue_id, i);
2612 BCMOLT_FIELD_SET(&egress_qos, egress_qos, type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2613 BCMOLT_FIELD_SET(&egress_qos.u.fixed_queue, egress_qos_fixed_queue, queue_id, tm_queue_id);
2614 } else {
2615 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid fixed queue priority/ID %d for GroupMember %d\n", member->priority(), i);
2616 bcmos_free(members.arr);
2617 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid queue priority for a group member");
2618 }
2619
2620 BCMOLT_FIELD_SET(&member_info, group_member_info, egress_qos, egress_qos);
2621 BCMOLT_ARRAY_ELEM_SET(&(members), i, member_info);
2622 }
2623
2624 BCMOLT_OPER_INIT(&grp_mem_upd, group, members_update, key);
2625 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.members, members);
2626 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.command, grp_mem_upd_cmd);
2627
2628 err = bcmolt_oper_submit(dev_id, &(grp_mem_upd.hdr));
2629 bcmos_free(members.arr);
2630
2631 if (BCM_ERR_OK != err) {
2632 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);
2633 return bcm_to_grpc_err(err, "Failed to submit members update operation for the group");
2634 }
2635
2636 OPENOLT_LOG(INFO, openolt_log_id, "Successfully submitted members update operation for Group %d\n", key.id);
2637
2638 return Status::OK;
2639}