blob: 691254b38a70792ba56628caa1745d5b3a6ff101 [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>
Shad Ansarib7b0ced2018-05-11 21:53:32 +000028
Craig Lutgen88a22ad2018-10-04 12:30:46 -050029#include "device.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000030#include "core.h"
31#include "indications.h"
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -040032#include "stats_collection.h"
Nicolas Palpacuer73222e02018-07-16 12:20:26 -040033#include "error_format.h"
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -040034#include "state.h"
Craig Lutgen88a22ad2018-10-04 12:30:46 -050035#include "utils.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000036
37extern "C"
38{
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000039#include <bcmolt_api.h>
40#include <bcmolt_host_api.h>
41#include <bcmolt_api_model_supporting_enums.h>
42
43#include <bal_version.h>
44#include <bcmolt_api_conn_mgr.h>
45//CLI header files
46#include <bcmcli_session.h>
47#include <bcmcli.h>
48#include <bcm_api_cli.h>
49
50#include <bcmos_common.h>
51#include <bcm_config.h>
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -040052// FIXME : dependency problem
53// #include <bcm_common_gpon.h>
Nicolas Palpacuer967438f2018-09-07 14:41:54 -040054// #include <bcm_dev_log_task.h>
Shad Ansarib7b0ced2018-05-11 21:53:32 +000055}
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000056
Shad Ansarib7b0ced2018-05-11 21:53:32 +000057
Nicolas Palpacuer967438f2018-09-07 14:41:54 -040058dev_log_id openolt_log_id = bcm_dev_log_id_register("OPENOLT", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
59dev_log_id omci_log_id = bcm_dev_log_id_register("OMCI", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
60
Craig Lutgen88a22ad2018-10-04 12:30:46 -050061#define BAL_RSC_MANAGER_BASE_TM_SCHED_ID 16384
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080062#define MAX_TM_QUEUE_ID 8192
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000063#define MAX_TM_QMP_ID 16
64#define TMQ_MAP_PROFILE_SIZE 8
65#define MAX_TM_SCHED_ID 1023
66#define MAX_SUBS_TM_SCHED_ID (MAX_SUPPORTED_PON == 16 ? MAX_TM_SCHED_ID-4-16 : MAX_TM_SCHED_ID-10-64)
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080067#define EAP_ETHER_TYPE 34958
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000068#define XGS_BANDWIDTH_GRANULARITY 16000
69#define GPON_BANDWIDTH_GRANULARITY 32000
70#define FILL_ARRAY(ARRAY,START,END,VALUE) for(int i=START;i<END;ARRAY[i++]=VALUE);
71#define COUNT_OF(array) (sizeof(array) / sizeof(array[0]))
72
73#define GET_FLOW_INTERFACE_TYPE(type) \
74 (type == BCMOLT_FLOW_INTERFACE_TYPE_PON) ? "PON" : \
75 (type == BCMOLT_FLOW_INTERFACE_TYPE_NNI) ? "NNI" : \
76 (type == BCMOLT_FLOW_INTERFACE_TYPE_HOST) ? "HOST" : "unknown"
77#define GET_PKT_TAG_TYPE(type) \
78 (type == BCMOLT_PKT_TAG_TYPE_UNTAGGED) ? "UNTAG" : \
79 (type == BCMOLT_PKT_TAG_TYPE_SINGLE_TAG) ? "SINGLE_TAG" : \
80 (type == BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG) ? "DOUBLE_TAG" : "unknown"
Nicolas Palpacuer967438f2018-09-07 14:41:54 -040081
Craig Lutgen88a22ad2018-10-04 12:30:46 -050082static unsigned int num_of_nni_ports = 0;
83static unsigned int num_of_pon_ports = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000084static std::string intf_technologies[MAX_SUPPORTED_PON];
Craig Lutgen88a22ad2018-10-04 12:30:46 -050085static const std::string UNKNOWN_TECH("unknown");
Craig Lutgenb2601f02018-10-23 13:04:31 -050086static const std::string MIXED_TECH("mixed");
87static std::string board_technology(UNKNOWN_TECH);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000088static std::string chip_family(UNKNOWN_TECH);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -080089static unsigned int OPENOLT_FIELD_LEN = 200;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000090static std::string firmware_version = "Openolt.2019.07.01";
Nicolas Palpacuerdff96792018-09-06 14:59:32 -040091
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000092const uint32_t tm_upstream_sched_id_start = (MAX_SUPPORTED_PON == 16 ? \
93 MAX_TM_SCHED_ID-3 : MAX_TM_SCHED_ID-9);
94const uint32_t tm_downstream_sched_id_start = (MAX_SUPPORTED_PON == 16 ? \
95 tm_upstream_sched_id_start-16 : tm_upstream_sched_id_start-64);
96
97/* Max Queue ID supported is 7 so based on priority_q configured for GEMPORTS
98in TECH PROFILE respective Queue ID from this list will be used for both
99US and DS Queues*/
100const uint32_t queue_id_list[8] = {0, 1, 2, 3, 4, 5, 6, 7};
101
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700102const std::string upstream = "upstream";
103const std::string downstream = "downstream";
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000104bcmolt_oltid dev_id = 0;
105
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000106/* Constants used for retrying some BAL APIs */
107const uint32_t BAL_API_RETRY_TIME_IN_USECS = 1000000;
108const uint32_t MAX_BAL_API_RETRY_COUNT = 5;
109
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000110/* Current session */
111static bcmcli_session *current_session;
112static bcmcli_entry *api_parent_dir;
113bcmos_bool status_bcm_cli_quit = BCMOS_FALSE;
114bcmos_task bal_cli_thread;
115const char *bal_cli_thread_name = "bal_cli_thread";
116uint16_t flow_id_counters = 0;
117int flow_id_data[16384][2];
Shad Ansariedef2132018-08-10 22:14:50 +0000118State state;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400119
Craig Lutgen967a1d02018-11-27 10:41:51 -0600120static std::map<uint32_t, uint32_t> flowid_to_port; // For mapping upstream flows to logical ports
121static std::map<uint32_t, uint32_t> flowid_to_gemport; // For mapping downstream flows into gemports
122static std::map<uint32_t, std::set<uint32_t> > port_to_flows; // For mapping logical ports to downstream flows
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800123
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000124/* This represents the Key to 'sched_map' map.
125 Represents (pon_intf_id, onu_id, uni_id, direction) */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800126typedef std::tuple<uint32_t, uint32_t, uint32_t, std::string> sched_map_key_tuple;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000127/* 'sched_map' maps sched_map_key_tuple to DBA (Upstream) or
128 Subscriber (Downstream) Scheduler ID */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800129static std::map<sched_map_key_tuple, int> sched_map;
130
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -0500131/* This represents the Key to 'qos_type_map' map.
132 Represents (pon_intf_id, onu_id, uni_id) */
133typedef std::tuple<uint32_t, uint32_t, uint32_t> qos_type_map_key_tuple;
134/* 'qos_type_map' maps qos_type_map_key_tuple to qos_type*/
135static std::map<qos_type_map_key_tuple, bcmolt_egress_qos_type> qos_type_map;
136
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000137/* This represents the Key to 'sched_qmp_id_map' map.
138Represents (sched_id, pon_intf_id, onu_id, uni_id) */
139typedef std::tuple<uint32_t, uint32_t, uint32_t, uint32_t> sched_qmp_id_map_key_tuple;
140/* 'sched_qmp_id_map' maps sched_qmp_id_map_key_tuple to TM Queue Mapping Profile ID */
141static std::map<sched_qmp_id_map_key_tuple, int> sched_qmp_id_map;
142/* 'qmp_id_to_qmp_map' maps TM Queue Mapping Profile ID to TM Queue Mapping Profile */
143static std::map<int, std::vector < uint32_t > > qmp_id_to_qmp_map;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800144
Girish Gowdra96461052019-11-22 20:13:59 +0530145#define ALLOC_CFG_COMPLETE_WAIT_TIMEOUT 1000 // in milli-seconds
146// Map used to track response from BAL for ITU PON Alloc Configuration.
147// The key is alloc_cfg_compltd_key and value is a concurrent thread-safe queue which is
148// used for pushing (from BAL) and popping (at application) the results.
149std::map<alloc_cfg_compltd_key, Queue<alloc_cfg_complete_result> *> alloc_cfg_compltd_map;
150// Lock to protect critical section data structure used for handling AllocObject configuration response.
151bcmos_fastlock alloc_cfg_wait_lock;
152
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800153std::bitset<MAX_TM_SCHED_ID> tm_sched_bitset;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000154std::bitset<MAX_TM_QMP_ID> tm_qmp_bitset;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800155
156static bcmos_fastlock data_lock;
Craig Lutgen967a1d02018-11-27 10:41:51 -0600157
Girish Gowdra96461052019-11-22 20:13:59 +0530158
Craig Lutgen967a1d02018-11-27 10:41:51 -0600159#define MIN_ALLOC_ID_GPON 256
160#define MIN_ALLOC_ID_XGSPON 1024
161
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800162static bcmos_errno CreateSched(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
163 uint32_t port_no, uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, \
164 uint32_t priority, tech_profile::SchedulingPolicy sched_policy,
165 tech_profile::TrafficShapingInfo traffic_shaping_info);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000166static 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 -0800167static 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 -0500168 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id);
169static bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
170 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000171static bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction);
172static bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction);
173
174uint16_t get_dev_id(void) {
175 return dev_id;
176}
Shad Ansari627b5782018-08-13 22:49:32 +0000177
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400178// Stubbed defntions of bcmolt_cfg_get required for unit-test
179#ifdef TEST_MODE
180extern bcmos_errno bcmolt_cfg_get__bal_state_stub(bcmolt_oltid olt_id, void* ptr);
181extern bcmos_errno bcmolt_cfg_get__olt_topology_stub(bcmolt_oltid olt_id, void* ptr);
182#endif
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800183/**
184* Returns the default NNI (Upstream direction) or PON (Downstream direction) scheduler
185* Every NNI port and PON port have default scheduler.
186* The NNI0 default scheduler ID is 18432, and NNI1 is 18433 and so on.
187* Similarly, PON0 default scheduler ID is 16384. PON1 is 16385 and so on.
188*
189* @param intf_id NNI or PON interface ID
190* @param direction "upstream" or "downstream"
191*
192* @return default scheduler ID for the given interface.
193*/
194static inline int get_default_tm_sched_id(int intf_id, std::string direction) {
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700195 if (direction.compare(upstream) == 0) {
196 return tm_upstream_sched_id_start + intf_id;
197 } else if (direction.compare(downstream) == 0) {
198 return tm_downstream_sched_id_start + intf_id;
199 }
200 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000201 OPENOLT_LOG(ERROR, openolt_log_id, "invalid direction - %s\n", direction.c_str());
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700202 return 0;
203 }
204}
205
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800206/**
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800207* Gets a unique tm_sched_id for a given intf_id, onu_id, uni_id, gemport_id, direction
208* The tm_sched_id is locally cached in a map, so that it can rendered when necessary.
209* VOLTHA replays whole configuration on OLT reboot, so caching locally is not a problem
210*
211* @param intf_id NNI or PON intf ID
212* @param onu_id ONU ID
213* @param uni_id UNI ID
214* @param gemport_id GEM Port ID
215* @param direction Upstream or downstream
216*
217* @return tm_sched_id
218*/
219uint32_t get_tm_sched_id(int pon_intf_id, int onu_id, int uni_id, std::string direction) {
220 sched_map_key_tuple key(pon_intf_id, onu_id, uni_id, direction);
221 int sched_id = -1;
222
223 std::map<sched_map_key_tuple, int>::const_iterator it = sched_map.find(key);
224 if (it != sched_map.end()) {
225 sched_id = it->second;
226 }
227 if (sched_id != -1) {
228 return sched_id;
229 }
230
231 bcmos_fastlock_lock(&data_lock);
232 // Complexity of O(n). Is there better way that can avoid linear search?
233 for (sched_id = 0; sched_id < MAX_TM_SCHED_ID; sched_id++) {
234 if (tm_sched_bitset[sched_id] == 0) {
235 tm_sched_bitset[sched_id] = 1;
236 break;
237 }
238 }
239 bcmos_fastlock_unlock(&data_lock, 0);
240
241 if (sched_id < MAX_TM_SCHED_ID) {
242 bcmos_fastlock_lock(&data_lock);
243 sched_map[key] = sched_id;
244 bcmos_fastlock_unlock(&data_lock, 0);
245 return sched_id;
246 } else {
247 return -1;
248 }
249}
250
251/**
252* Free tm_sched_id for a given intf_id, onu_id, uni_id, gemport_id, direction
253*
254* @param intf_id NNI or PON intf ID
255* @param onu_id ONU ID
256* @param uni_id UNI ID
257* @param gemport_id GEM Port ID
258* @param direction Upstream or downstream
259*/
260void free_tm_sched_id(int pon_intf_id, int onu_id, int uni_id, std::string direction) {
261 sched_map_key_tuple key(pon_intf_id, onu_id, uni_id, direction);
262 std::map<sched_map_key_tuple, int>::const_iterator it;
263 bcmos_fastlock_lock(&data_lock);
264 it = sched_map.find(key);
265 if (it != sched_map.end()) {
266 tm_sched_bitset[it->second] = 0;
267 sched_map.erase(it);
268 }
269 bcmos_fastlock_unlock(&data_lock, 0);
270}
271
272bool is_tm_sched_id_present(int pon_intf_id, int onu_id, int uni_id, std::string direction) {
273 sched_map_key_tuple key(pon_intf_id, onu_id, uni_id, direction);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000274 std::map<sched_map_key_tuple, int>::const_iterator it = sched_map.find(key);
275 if (it != sched_map.end()) {
276 return true;
277 }
278 return false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800279}
280
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000281/**
282* Check whether given two tm qmp profiles are equal or not
283*
284* @param tmq_map_profileA <vector> TM QUEUE MAPPING PROFILE
285* @param tmq_map_profileB <vector> TM QUEUE MAPPING PROFILE
286*
287* @return boolean, true if given tmq_map_profiles are equal else false
288*/
289
290bool check_tm_qmp_equality(std::vector<uint32_t> tmq_map_profileA, std::vector<uint32_t> tmq_map_profileB) {
291 for (uint32_t i = 0; i < TMQ_MAP_PROFILE_SIZE; i++) {
292 if (tmq_map_profileA[i] != tmq_map_profileB[i]) {
293 return false;
294 }
295 }
296 return true;
Shad Ansari627b5782018-08-13 22:49:32 +0000297}
298
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000299/**
300* Modifies given queues_pbit_map to parsable format
301* e.g: Modifes "0b00000101" to "10100000"
302*
303* @param queues_pbit_map PBIT MAP configured for each GEM in TECH PROFILE
304* @param size Queue count
305*
306* @return string queues_pbit_map
307*/
308std::string* get_valid_queues_pbit_map(std::string *queues_pbit_map, uint32_t size) {
309 for(uint32_t i=0; i < size; i++) {
310 /* Deletes 2 characters from index number 0 */
311 queues_pbit_map[i].erase(0, 2);
312 std::reverse(queues_pbit_map[i].begin(), queues_pbit_map[i].end());
313 }
314 return queues_pbit_map;
315}
316
317/**
318* Creates TM QUEUE MAPPING PROFILE for given queues_pbit_map and queues_priority_q
319*
320* @param queues_pbit_map PBIT MAP configured for each GEM in TECH PROFILE
321* @param queues_priority_q PRIORITY_Q configured for each GEM in TECH PROFILE
322* @param size Queue count
323*
324* @return <vector> TM QUEUE MAPPING PROFILE
325*/
326std::vector<uint32_t> get_tmq_map_profile(std::string *queues_pbit_map, uint32_t *queues_priority_q, uint32_t size) {
327 std::vector<uint32_t> tmq_map_profile(8,0);
328
329 for(uint32_t i=0; i < size; i++) {
330 for (uint32_t j = 0; j < queues_pbit_map[i].size(); j++) {
331 if (queues_pbit_map[i][j]=='1') {
332 tmq_map_profile.at(j) = queue_id_list[queues_priority_q[i]];
333 }
334 }
335 }
336 return tmq_map_profile;
337}
338
339/**
340* Gets corresponding tm_qmp_id for a given tmq_map_profile
341*
342* @param <vector> TM QUEUE MAPPING PROFILE
343*
344* @return tm_qmp_id
345*/
346int get_tm_qmp_id(std::vector<uint32_t> tmq_map_profile) {
347 int tm_qmp_id = -1;
348
349 std::map<int, std::vector < uint32_t > >::const_iterator it = qmp_id_to_qmp_map.begin();
350 while(it != qmp_id_to_qmp_map.end()) {
351 if(check_tm_qmp_equality(tmq_map_profile, it->second)) {
352 tm_qmp_id = it->first;
353 break;
354 }
355 it++;
356 }
357 return tm_qmp_id;
358}
359
360/**
361* Updates sched_qmp_id_map with given sched_id, pon_intf_id, onu_id, uni_id, tm_qmp_id
362*
363* @param upstream/downstream sched_id
364* @param PON intf ID
365* @param onu_id ONU ID
366* @param uni_id UNI ID
367* @param tm_qmp_id TM QUEUE MAPPING PROFILE ID
368*/
369void update_sched_qmp_id_map(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, \
370 uint32_t uni_id, int tm_qmp_id) {
371 bcmos_fastlock_lock(&data_lock);
372 sched_qmp_id_map_key_tuple key(sched_id, pon_intf_id, onu_id, uni_id);
373 sched_qmp_id_map.insert(make_pair(key, tm_qmp_id));
374 bcmos_fastlock_unlock(&data_lock, 0);
375}
376
377/**
378* Gets corresponding tm_qmp_id for a given sched_id, pon_intf_id, onu_id, uni_id
379*
380* @param upstream/downstream sched_id
381* @param PON intf ID
382* @param onu_id ONU ID
383* @param uni_id UNI ID
384*
385* @return tm_qmp_id
386*/
387int get_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id) {
388 sched_qmp_id_map_key_tuple key(sched_id, pon_intf_id, onu_id, uni_id);
389 int tm_qmp_id = -1;
390
391 std::map<sched_qmp_id_map_key_tuple, int>::const_iterator it = sched_qmp_id_map.find(key);
392 if (it != sched_qmp_id_map.end()) {
393 tm_qmp_id = it->second;
394 }
395 return tm_qmp_id;
396}
397
398/**
399* Gets a unique tm_qmp_id for a given tmq_map_profile
400* The tm_qmp_id is locally cached in a map, so that it can be rendered when necessary.
401* VOLTHA replays whole configuration on OLT reboot, so caching locally is not a problem
402*
403* @param upstream/downstream sched_id
404* @param PON intf ID
405* @param onu_id ONU ID
406* @param uni_id UNI ID
407* @param <vector> TM QUEUE MAPPING PROFILE
408*
409* @return tm_qmp_id
410*/
411int get_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id, \
412 std::vector<uint32_t> tmq_map_profile) {
413 int tm_qmp_id;
414
415 bcmos_fastlock_lock(&data_lock);
416 /* Complexity of O(n). Is there better way that can avoid linear search? */
417 for (tm_qmp_id = 0; tm_qmp_id < MAX_TM_QMP_ID; tm_qmp_id++) {
418 if (tm_qmp_bitset[tm_qmp_id] == 0) {
419 tm_qmp_bitset[tm_qmp_id] = 1;
420 break;
421 }
422 }
423 bcmos_fastlock_unlock(&data_lock, 0);
424
425 if (tm_qmp_id < MAX_TM_QMP_ID) {
426 bcmos_fastlock_lock(&data_lock);
427 qmp_id_to_qmp_map.insert(make_pair(tm_qmp_id, tmq_map_profile));
428 bcmos_fastlock_unlock(&data_lock, 0);
429 update_sched_qmp_id_map(sched_id, pon_intf_id, onu_id, uni_id, tm_qmp_id);
430 return tm_qmp_id;
431 } else {
432 return -1;
433 }
434}
435
436/**
437* Free tm_qmp_id for a given sched_id, pon_intf_id, onu_id, uni_id
438*
439* @param upstream/downstream sched_id
440* @param PON intf ID
441* @param onu_id ONU ID
442* @param uni_id UNI ID
443* @param tm_qmp_id TM QUEUE MAPPING PROFILE ID
444*
445* @return boolean, true if no more reference for TM QMP else false
446*/
447bool free_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, \
448 uint32_t uni_id, int tm_qmp_id) {
449 bool result;
450 sched_qmp_id_map_key_tuple key(sched_id, pon_intf_id, onu_id, uni_id);
451 std::map<sched_qmp_id_map_key_tuple, int>::const_iterator it = sched_qmp_id_map.find(key);
452 bcmos_fastlock_lock(&data_lock);
453 if (it != sched_qmp_id_map.end()) {
454 sched_qmp_id_map.erase(it);
455 }
456 bcmos_fastlock_unlock(&data_lock, 0);
457
458 uint32_t tm_qmp_ref_count = 0;
459 std::map<sched_qmp_id_map_key_tuple, int>::const_iterator it2 = sched_qmp_id_map.begin();
460 while(it2 != sched_qmp_id_map.end()) {
461 if(it2->second == tm_qmp_id) {
462 tm_qmp_ref_count++;
463 }
464 it2++;
465 }
466
467 if (tm_qmp_ref_count == 0) {
468 std::map<int, std::vector < uint32_t > >::const_iterator it3 = qmp_id_to_qmp_map.find(tm_qmp_id);
469 if (it3 != qmp_id_to_qmp_map.end()) {
470 bcmos_fastlock_lock(&data_lock);
471 tm_qmp_bitset[tm_qmp_id] = 0;
472 qmp_id_to_qmp_map.erase(it3);
473 bcmos_fastlock_unlock(&data_lock, 0);
474 OPENOLT_LOG(INFO, openolt_log_id, "Reference count for tm qmp profile id %d is : %d. So clearing it\n", \
475 tm_qmp_id, tm_qmp_ref_count);
476 result = true;
477 }
478 } else {
479 OPENOLT_LOG(INFO, openolt_log_id, "Reference count for tm qmp profile id %d is : %d. So not clearing it\n", \
480 tm_qmp_id, tm_qmp_ref_count);
481 result = false;
482 }
483 return result;
484}
485
486/**
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -0500487* Returns qos type as string
488*
489* @param qos_type bcmolt_egress_qos_type enum
490*/
491std::string get_qos_type_as_string(bcmolt_egress_qos_type qos_type) {
492 switch (qos_type)
493 {
494 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE: return "FIXED_QUEUE";
495 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE: return "TC_TO_QUEUE";
496 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC: return "PBIT_TO_TC";
497 case BCMOLT_EGRESS_QOS_TYPE_NONE: return "NONE";
498 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE: return "PRIORITY_TO_QUEUE";
499 default: OPENOLT_LOG(ERROR, openolt_log_id, "qos-type-not-supported %d\n", qos_type);
500 return "qos-type-not-supported";
501 }
502}
503
504/**
505* Gets/Updates qos type for given pon_intf_id, onu_id, uni_id
506*
507* @param PON intf ID
508* @param onu_id ONU ID
509* @param uni_id UNI ID
510* @param queue_size TrafficQueues Size
511*
512* @return qos_type
513*/
514bcmolt_egress_qos_type get_qos_type(uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t queue_size = 0) {
515 qos_type_map_key_tuple key(pon_intf_id, onu_id, uni_id);
516 bcmolt_egress_qos_type egress_qos_type = BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE;
517 std::string qos_string;
518
519 std::map<qos_type_map_key_tuple, bcmolt_egress_qos_type>::const_iterator it = qos_type_map.find(key);
520 if (it != qos_type_map.end()) {
521 egress_qos_type = it->second;
522 qos_string = get_qos_type_as_string(egress_qos_type);
523 OPENOLT_LOG(INFO, openolt_log_id, "Qos-type for subscriber connected to pon_intf_id %d, onu_id %d and uni_id %d is %s\n", \
524 pon_intf_id, onu_id, uni_id, qos_string.c_str());
525 }
526 else {
527 /* QOS Type has been pre-defined as Fixed Queue but it will be updated based on number of GEMPORTS
528 associated for a given subscriber. If GEM count = 1 for a given subscriber, qos_type will be Fixed Queue
529 else Priority to Queue */
530 egress_qos_type = (queue_size > 1) ? \
531 BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE : BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE;
532 bcmos_fastlock_lock(&data_lock);
533 qos_type_map.insert(make_pair(key, egress_qos_type));
534 bcmos_fastlock_unlock(&data_lock, 0);
535 qos_string = get_qos_type_as_string(egress_qos_type);
536 OPENOLT_LOG(INFO, openolt_log_id, "Qos-type for subscriber connected to pon_intf_id %d, onu_id %d and uni_id %d is %s\n", \
537 pon_intf_id, onu_id, uni_id, qos_string.c_str());
538 }
539 return egress_qos_type;
540}
541
542/**
543* Clears qos type for given pon_intf_id, onu_id, uni_id
544*
545* @param PON intf ID
546* @param onu_id ONU ID
547* @param uni_id UNI ID
548*/
549void clear_qos_type(uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id) {
550 qos_type_map_key_tuple key(pon_intf_id, onu_id, uni_id);
551 std::map<qos_type_map_key_tuple, bcmolt_egress_qos_type>::const_iterator it = qos_type_map.find(key);
552 bcmos_fastlock_lock(&data_lock);
553 if (it != qos_type_map.end()) {
554 qos_type_map.erase(it);
555 OPENOLT_LOG(INFO, openolt_log_id, "Cleared Qos-type for subscriber connected to pon_intf_id %d, onu_id %d and uni_id %d\n", \
556 pon_intf_id, onu_id, uni_id);
557 }
558 bcmos_fastlock_unlock(&data_lock, 0);
559}
560
561/**
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000562* Returns Scheduler/Queue direction as string
563*
564* @param direction as specified in tech_profile.proto
565*/
566std::string GetDirection(int direction) {
567 switch (direction)
568 {
569 case tech_profile::Direction::UPSTREAM: return upstream;
570 case tech_profile::Direction::DOWNSTREAM: return downstream;
571 default: OPENOLT_LOG(ERROR, openolt_log_id, "direction-not-supported %d\n", direction);
572 return "direction-not-supported";
573 }
574}
575
576inline const char *get_flow_acton_command(uint32_t command) {
577 char actions[200] = { };
578 char *s_actions_ptr = actions;
579 if (command & BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG) strcat(s_actions_ptr, "ADD_OUTER_TAG|");
580 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG) strcat(s_actions_ptr, "REMOVE_OUTER_TAG|");
581 if (command & BCMOLT_ACTION_CMD_ID_XLATE_OUTER_TAG) strcat(s_actions_ptr, "TRANSLATE_OUTER_TAG|");
582 if (command & BCMOLT_ACTION_CMD_ID_ADD_INNER_TAG) strcat(s_actions_ptr, "ADD_INNTER_TAG|");
583 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_INNER_TAG) strcat(s_actions_ptr, "REMOVE_INNER_TAG|");
584 if (command & BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG) strcat(s_actions_ptr, "TRANSLATE_INNER_TAG|");
585 if (command & BCMOLT_ACTION_CMD_ID_REMARK_OUTER_PBITS) strcat(s_actions_ptr, "REMOVE_OUTER_PBITS|");
586 if (command & BCMOLT_ACTION_CMD_ID_REMARK_INNER_PBITS) strcat(s_actions_ptr, "REMAKE_INNER_PBITS|");
587 return s_actions_ptr;
588}
589
Girish Gowdra96461052019-11-22 20:13:59 +0530590// This method handles waiting for AllocObject configuration.
591// Returns error if the AllocObject is not in the appropriate state based on action requested.
592bcmos_errno wait_for_alloc_action(uint32_t intf_id, uint32_t alloc_id, AllocCfgAction action) {
593 Queue<alloc_cfg_complete_result> cfg_result;
594 alloc_cfg_compltd_key k(intf_id, alloc_id);
595 alloc_cfg_compltd_map[k] = &cfg_result;
596 bcmos_errno err = BCM_ERR_OK;
597
598 // Try to pop the result from BAL with a timeout of ALLOC_CFG_COMPLETE_WAIT_TIMEOUT ms
599 std::pair<alloc_cfg_complete_result, bool> result = cfg_result.pop(ALLOC_CFG_COMPLETE_WAIT_TIMEOUT);
600 if (result.second == false) {
601 OPENOLT_LOG(ERROR, openolt_log_id, "timeout waiting for alloc cfg complete indication intf_id %d, alloc_id %d\n",
602 intf_id, alloc_id);
603 // Invalidate the queue pointer.
604 bcmos_fastlock_lock(&alloc_cfg_wait_lock);
605 alloc_cfg_compltd_map[k] = NULL;
606 bcmos_fastlock_unlock(&alloc_cfg_wait_lock, 0);
607 err = BCM_ERR_INTERNAL;
608 }
609 else if (result.first.status == ALLOC_CFG_STATUS_FAIL) {
610 OPENOLT_LOG(ERROR, openolt_log_id, "error processing alloc cfg request intf_id %d, alloc_id %d\n",
611 intf_id, alloc_id);
612 err = BCM_ERR_INTERNAL;
613 }
614
615 if (err == BCM_ERR_OK) {
616 if (action == ALLOC_OBJECT_CREATE) {
617 if (result.first.state != ALLOC_OBJECT_STATE_ACTIVE) {
618 OPENOLT_LOG(ERROR, openolt_log_id, "alloc object not in active state intf_id %d, alloc_id %d alloc_obj_state %d\n",
619 intf_id, alloc_id, result.first.state);
620 err = BCM_ERR_INTERNAL;
621 } else {
622 OPENOLT_LOG(INFO, openolt_log_id, "Create upstream bandwidth allocation success, intf_id %d, alloc_id %d\n",
623 intf_id, alloc_id);
624 }
625 } else { // ALLOC_OBJECT_DELETE
626 if (result.first.state != ALLOC_OBJECT_STATE_NOT_CONFIGURED) {
627 OPENOLT_LOG(ERROR, openolt_log_id, "alloc object is not reset intf_id %d, alloc_id %d alloc_obj_state %d\n",
628 intf_id, alloc_id, result.first.state);
629 err = BCM_ERR_INTERNAL;
630 } else {
631 OPENOLT_LOG(INFO, openolt_log_id, "Remove alloc object success, intf_id %d, alloc_id %d\n",
632 intf_id, alloc_id);
633 }
634 }
635 }
636
637 // Remove entry from map
638 bcmos_fastlock_lock(&alloc_cfg_wait_lock);
639 alloc_cfg_compltd_map.erase(k);
640 bcmos_fastlock_unlock(&alloc_cfg_wait_lock, 0);
641 return err;
642}
643
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000644char* openolt_read_sysinfo(const char* field_name, char* field_val)
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800645{
646 FILE *fp;
647 /* Prepare the command*/
648 char command[150];
649
650 snprintf(command, sizeof command, "bash -l -c \"onlpdump -s\" | perl -ne 'print $1 if /%s: (\\S+)/'", field_name);
651 /* Open the command for reading. */
652 fp = popen(command, "r");
653 if (fp == NULL) {
654 /*The client has to check for a Null field value in this case*/
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000655 OPENOLT_LOG(INFO, openolt_log_id, "Failed to query the %s\n", field_name);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800656 return field_val;
657 }
658
659 /*Read the field value*/
660 if (fp) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000661 uint8_t ret;
662 ret = fread(field_val, OPENOLT_FIELD_LEN, 1, fp);
663 if (ret >= OPENOLT_FIELD_LEN)
664 OPENOLT_LOG(INFO, openolt_log_id, "Read data length %u\n", ret);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800665 pclose(fp);
666 }
667 return field_val;
668}
669
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400670Status GetDeviceInfo_(openolt::DeviceInfo* device_info) {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500671 device_info->set_vendor(VENDOR_ID);
672 device_info->set_model(MODEL_ID);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400673 device_info->set_hardware_version("");
674 device_info->set_firmware_version(firmware_version);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500675 device_info->set_technology(board_technology);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500676 device_info->set_pon_ports(num_of_pon_ports);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500677
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800678 char serial_number[OPENOLT_FIELD_LEN];
679 memset(serial_number, '\0', OPENOLT_FIELD_LEN);
680 openolt_read_sysinfo("Serial Number", serial_number);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000681 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device serial number %s\n", serial_number);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800682 device_info->set_device_serial_number(serial_number);
683
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700684 char device_id[OPENOLT_FIELD_LEN];
685 memset(device_id, '\0', OPENOLT_FIELD_LEN);
686 openolt_read_sysinfo("MAC", device_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000687 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device mac address %s\n", device_id);
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700688 device_info->set_device_id(device_id);
689
Craig Lutgenb2601f02018-10-23 13:04:31 -0500690 // Legacy, device-wide ranges. To be deprecated when adapter
691 // is upgraded to support per-interface ranges
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000692 if (board_technology == "XGS-PON") {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500693 device_info->set_onu_id_start(1);
694 device_info->set_onu_id_end(255);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600695 device_info->set_alloc_id_start(MIN_ALLOC_ID_XGSPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500696 device_info->set_alloc_id_end(16383);
697 device_info->set_gemport_id_start(1024);
698 device_info->set_gemport_id_end(65535);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500699 device_info->set_flow_id_start(1);
700 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500701 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000702 else if (board_technology == "GPON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500703 device_info->set_onu_id_start(1);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500704 device_info->set_onu_id_end(127);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600705 device_info->set_alloc_id_start(MIN_ALLOC_ID_GPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500706 device_info->set_alloc_id_end(767);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500707 device_info->set_gemport_id_start(256);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500708 device_info->set_gemport_id_end(4095);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500709 device_info->set_flow_id_start(1);
710 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500711 }
Craig Lutgenb2601f02018-10-23 13:04:31 -0500712
713 std::map<std::string, openolt::DeviceInfo::DeviceResourceRanges*> ranges;
714 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
715 std::string intf_technology = intf_technologies[intf_id];
716 openolt::DeviceInfo::DeviceResourceRanges *range = ranges[intf_technology];
717 if(range == nullptr) {
718 range = device_info->add_ranges();
719 ranges[intf_technology] = range;
720 range->set_technology(intf_technology);
721
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000722 if (intf_technology == "XGS-PON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500723 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
724
725 pool = range->add_pools();
726 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
727 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
728 pool->set_start(1);
729 pool->set_end(255);
730
731 pool = range->add_pools();
732 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
733 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_SAME_TECH);
734 pool->set_start(1024);
735 pool->set_end(16383);
736
737 pool = range->add_pools();
738 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
739 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
740 pool->set_start(1024);
741 pool->set_end(65535);
742
743 pool = range->add_pools();
744 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
745 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
746 pool->set_start(1);
747 pool->set_end(16383);
748 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000749 else if (intf_technology == "GPON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500750 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
751
752 pool = range->add_pools();
753 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
754 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
755 pool->set_start(1);
756 pool->set_end(127);
757
758 pool = range->add_pools();
759 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
760 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_SAME_TECH);
761 pool->set_start(256);
762 pool->set_end(757);
763
764 pool = range->add_pools();
765 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
766 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
767 pool->set_start(256);
768 pool->set_end(4095);
769
770 pool = range->add_pools();
771 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
772 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
773 pool->set_start(1);
774 pool->set_end(16383);
775 }
776 }
777
778 range->add_intf_ids(intf_id);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500779 }
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400780
781 // FIXME: Once dependency problem is fixed
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500782 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400783 // device_info->set_onu_id_end(XGPON_NUM_OF_ONUS - 1);
784 // device_info->set_alloc_id_start(1024);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500785 // device_info->set_alloc_id_end(XGPON_NUM_OF_ALLOC_IDS * num_of_pon_ports ? - 1);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400786 // device_info->set_gemport_id_start(XGPON_MIN_BASE_SERVICE_PORT_ID);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500787 // device_info->set_gemport_id_end(XGPON_NUM_OF_GEM_PORT_IDS_PER_PON * num_of_pon_ports ? - 1);
788 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400789
790 return Status::OK;
791}
792
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000793Status pushOltOperInd(uint32_t intf_id, const char *type, const char *state)
794{
795 openolt::Indication ind;
796 openolt::IntfOperIndication* intf_oper_ind = new openolt::IntfOperIndication;
797
798 intf_oper_ind->set_type(type);
799 intf_oper_ind->set_intf_id(intf_id);
800 intf_oper_ind->set_oper_state(state);
801 ind.set_allocated_intf_oper_ind(intf_oper_ind);
802 oltIndQ.push(ind);
803 return Status::OK;
804}
805
806#define CLI_HOST_PROMPT_FORMAT "BCM.%u> "
807
808/* Build CLI prompt */
809static void openolt_cli_get_prompt_cb(bcmcli_session *session, char *buf, uint32_t max_len)
810{
811 snprintf(buf, max_len, CLI_HOST_PROMPT_FORMAT, dev_id);
812}
813
814static int _bal_apiend_cli_thread_handler(long data)
815{
816 char init_string[]="\n";
817 bcmcli_session *sess = current_session;
818 bcmos_task_parm bal_cli_task_p_dummy;
819
820 /* Switch to interactive mode if not stopped in the init script */
821 if (!bcmcli_is_stopped(sess))
822 {
823 /* Force a CLI command prompt
824 * The string passed into the parse function
825 * must be modifiable, so a string constant like
826 * bcmcli_parse(current_session, "\n") will not
827 * work.
828 */
829 bcmcli_parse(sess, init_string);
830
831 /* Process user input until EOF or quit command */
832 bcmcli_driver(sess);
833 };
834 OPENOLT_LOG(INFO, openolt_log_id, "BAL API End CLI terminated\n");
835
836 /* Cleanup */
837 bcmcli_session_close(current_session);
838 bcmcli_token_destroy(NULL);
839 return 0;
840}
841
842/* Init API CLI commands for the current device */
843bcmos_errno bcm_openolt_api_cli_init(bcmcli_entry *parent_dir, bcmcli_session *session)
844{
845 bcmos_errno rc;
846
847 api_parent_dir = parent_dir;
848
849 rc = bcm_api_cli_set_commands(session);
850
851#ifdef BCM_SUBSYSTEM_HOST
852 /* Subscribe for device change indication */
853 rc = rc ? rc : bcmolt_olt_sel_ind_register(_api_cli_olt_change_ind);
854#endif
855
856 return rc;
857}
858
859static bcmos_errno bcm_cli_quit(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
860{
861 bcmcli_stop(session);
862 bcmcli_session_print(session, "CLI terminated by 'Quit' command\n");
863 status_bcm_cli_quit = BCMOS_TRUE;
864
865 return BCM_ERR_OK;
866}
867
868int get_status_bcm_cli_quit(void) {
869 return status_bcm_cli_quit;
870}
871
872bcmos_errno bcmolt_apiend_cli_init() {
873 bcmos_errno ret;
874 bcmos_task_parm bal_cli_task_p = {};
875 bcmos_task_parm bal_cli_task_p_dummy;
876
877 /** before creating the task, check if it is already created by the other half of BAL i.e. Core side */
878 if (BCM_ERR_OK != bcmos_task_query(&bal_cli_thread, &bal_cli_task_p_dummy))
879 {
880 /* Create BAL CLI thread */
881 bal_cli_task_p.name = bal_cli_thread_name;
882 bal_cli_task_p.handler = _bal_apiend_cli_thread_handler;
883 bal_cli_task_p.priority = TASK_PRIORITY_CLI;
884
885 ret = bcmos_task_create(&bal_cli_thread, &bal_cli_task_p);
886 if (BCM_ERR_OK != ret)
887 {
888 bcmos_printf("Couldn't create BAL API end CLI thread\n");
889 return ret;
890 }
891 }
892}
893
Shad Ansari627b5782018-08-13 22:49:32 +0000894Status Enable_(int argc, char *argv[]) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000895 bcmos_errno err;
896 bcmolt_host_init_parms init_parms = {};
897 init_parms.transport.type = BCM_HOST_API_CONN_LOCAL;
898 unsigned int failed_enable_device_cnt = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000899
Shad Ansariedef2132018-08-10 22:14:50 +0000900 if (!state.is_activated()) {
Shad Ansari627b5782018-08-13 22:49:32 +0000901
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500902 vendor_init();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000903 /* Initialize host subsystem */
904 err = bcmolt_host_init(&init_parms);
905 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500906 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to init OLT, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000907 return bcm_to_grpc_err(err, "Failed to init OLT");
908 }
909
910 bcmcli_session_parm mon_session_parm;
911 /* Create CLI session */
912 memset(&mon_session_parm, 0, sizeof(mon_session_parm));
913 mon_session_parm.get_prompt = openolt_cli_get_prompt_cb;
914 mon_session_parm.access_right = BCMCLI_ACCESS_ADMIN;
915 bcmos_errno rc = bcmcli_session_open(&mon_session_parm, &current_session);
916 BUG_ON(rc != BCM_ERR_OK);
917
918 /* API CLI */
919 bcm_openolt_api_cli_init(NULL, current_session);
920
921 /* Add quit command */
922 BCMCLI_MAKE_CMD_NOPARM(NULL, "quit", "Quit", bcm_cli_quit);
923
924 err = bcmolt_apiend_cli_init();
925 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500926 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to add apiend init, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000927 return bcm_to_grpc_err(err, "Failed to add apiend init");
928 }
929
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800930 bcmos_fastlock_init(&data_lock, 0);
Girish Gowdra96461052019-11-22 20:13:59 +0530931 bcmos_fastlock_init(&alloc_cfg_wait_lock, 0);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000932 OPENOLT_LOG(INFO, openolt_log_id, "Enable OLT - %s-%s\n", VENDOR_ID, MODEL_ID);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600933
Jason Huangbf45ffb2019-10-30 17:29:02 +0800934 //check BCM daemon is connected or not
935 Status status = check_connection();
936 if (!status.ok())
937 return status;
938 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000939 Status status = SubscribeIndication();
940 if (!status.ok()) {
941 OPENOLT_LOG(ERROR, openolt_log_id, "SubscribeIndication failed - %s : %s\n",
942 grpc_status_code_to_string(status.error_code()).c_str(),
943 status.error_message().c_str());
944 return status;
945 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800946
947 //check BAL state in initial stage
948 status = check_bal_ready();
949 if (!status.ok())
950 return status;
951 }
952
953 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000954 bcmos_errno err;
955 bcmolt_odid dev;
956 OPENOLT_LOG(INFO, openolt_log_id, "Enabling PON %d Devices ... \n", BCM_MAX_DEVS_PER_LINE_CARD);
957 for (dev = 0; dev < BCM_MAX_DEVS_PER_LINE_CARD; dev++) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400958 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000959 bcmolt_device_key dev_key = { };
960 dev_key.device_id = dev;
961 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
962 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
963 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
Jason Huangbf45ffb2019-10-30 17:29:02 +0800964 if (err == BCM_ERR_NOT_CONNECTED) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000965 bcmolt_device_key key = {.device_id = dev};
966 bcmolt_device_connect oper;
967 BCMOLT_OPER_INIT(&oper, device, connect, key);
968 if (MODEL_ID == "asfvolt16") {
969 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
970 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_XGS__2_X);
971 } else if (MODEL_ID == "asgvolt64") {
972 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
973 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
974 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
975 }
976 err = bcmolt_oper_submit(dev_id, &oper.hdr);
977 if (err) {
978 failed_enable_device_cnt ++;
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500979 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 +0000980 if (failed_enable_device_cnt == BCM_MAX_DEVS_PER_LINE_CARD) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500981 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 +0000982 return Status(grpc::StatusCode::INTERNAL, "Failed to activate all PON ports");
983 }
984 }
985 bcmos_usleep(200000);
986 }
987 else {
988 OPENOLT_LOG(WARNING, openolt_log_id, "PON deivce %d already connected\n", dev);
989 state.activate();
990 }
991 }
992 init_stats();
Shad Ansari627b5782018-08-13 22:49:32 +0000993 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000994 }
Shad Ansariedef2132018-08-10 22:14:50 +0000995
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000996 /* Start CLI */
997 OPENOLT_LOG(INFO, def_log_id, "Starting CLI\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400998 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000999 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001000}
1001
1002Status Disable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001003 //In the earlier implementation Disabling olt is done by disabling the NNI port associated with that.
1004 //In inband scenario instead of using management interface to establish connection with adapter ,NNI interface will be used.
1005 //Disabling NNI port on olt disable causes connection loss between adapter and agent.
1006 //To overcome this disable is implemented by disabling all the PON ports
1007 //associated with the device so as to support both in-band
1008 //and out of band scenarios.
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001009
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001010 Status status;
1011 int failedCount = 0;
1012 for (int i = 0; i < NumPonIf_(); i++) {
1013 status = DisablePonIf_(i);
1014 if (!status.ok()) {
1015 failedCount+=1;
1016 BCM_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", i);
1017 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001018 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001019 if (failedCount == 0) {
1020 state.deactivate();
1021 openolt::Indication ind;
1022 openolt::OltIndication* olt_ind = new openolt::OltIndication;
1023 olt_ind->set_oper_state("down");
1024 ind.set_allocated_olt_ind(olt_ind);
1025 BCM_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
1026 oltIndQ.push(ind);
1027 return Status::OK;
1028 }
1029 if (failedCount ==NumPonIf_()){
1030 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to disable olt ,all the PON ports are still in enabled state");
1031 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001032
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001033 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 -04001034}
1035
1036Status Reenable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001037 Status status;
1038 int failedCount = 0;
1039 for (int i = 0; i < NumPonIf_(); i++) {
1040 status = EnablePonIf_(i);
1041 if (!status.ok()) {
1042 failedCount+=1;
1043 BCM_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", i);
1044 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001045 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001046 if (failedCount == 0){
1047 state.activate();
1048 openolt::Indication ind;
1049 openolt::OltIndication* olt_ind = new openolt::OltIndication;
1050 olt_ind->set_oper_state("up");
1051 ind.set_allocated_olt_ind(olt_ind);
1052 BCM_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
1053 oltIndQ.push(ind);
1054 return Status::OK;
1055 }
1056 if (failedCount ==NumPonIf_()){
1057 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to re-enable olt ,all the PON ports are still in disabled state");
1058 }
1059 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 +00001060}
1061
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001062bcmos_errno get_pon_interface_status(bcmolt_interface pon_ni, bcmolt_interface_state *state) {
1063 bcmos_errno err;
1064 bcmolt_pon_interface_key pon_key;
1065 bcmolt_pon_interface_cfg pon_cfg;
1066 pon_key.pon_ni = pon_ni;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001067
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001068 BCMOLT_CFG_INIT(&pon_cfg, pon_interface, pon_key);
1069 BCMOLT_FIELD_SET_PRESENT(&pon_cfg.data, pon_interface_cfg_data, state);
1070 BCMOLT_FIELD_SET_PRESENT(&pon_cfg.data, pon_interface_cfg_data, itu);
1071 err = bcmolt_cfg_get(dev_id, &pon_cfg.hdr);
1072 *state = pon_cfg.data.state;
1073 return err;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001074}
1075
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001076inline uint64_t get_flow_status(uint16_t flow_id, uint16_t flow_type, uint16_t data_id) {
1077 bcmos_errno err;
1078 bcmolt_flow_key flow_key;
1079 bcmolt_flow_cfg flow_cfg;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001080
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001081 flow_key.flow_id = flow_id;
1082 flow_key.flow_type = (bcmolt_flow_type)flow_type;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001083
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001084 BCMOLT_CFG_INIT(&flow_cfg, flow, flow_key);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001085
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001086 switch (data_id) {
1087 case ONU_ID: //onu_id
1088 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, onu_id);
1089 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1090 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001091 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get onu_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001092 return err;
1093 }
1094 return flow_cfg.data.onu_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001095 case FLOW_TYPE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001096 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1097 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001098 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get flow_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001099 return err;
1100 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001101 return flow_cfg.key.flow_type;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001102 case SVC_PORT_ID: //svc_port_id
1103 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, svc_port_id);
1104 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1105 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001106 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 +00001107 return err;
1108 }
1109 return flow_cfg.data.svc_port_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001110 case PRIORITY:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001111 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, priority);
1112 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1113 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001114 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get priority, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001115 return err;
1116 }
1117 return flow_cfg.data.priority;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001118 case COOKIE: //cookie
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001119 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, cookie);
1120 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1121 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001122 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get cookie, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001123 return err;
1124 }
1125 return flow_cfg.data.cookie;
1126 case INGRESS_INTF_TYPE: //ingress intf_type
1127 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
1128 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1129 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001130 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 +00001131 return err;
1132 }
1133 return flow_cfg.data.ingress_intf.intf_type;
1134 case EGRESS_INTF_TYPE: //egress intf_type
1135 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
1136 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1137 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001138 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 +00001139 return err;
1140 }
1141 return flow_cfg.data.egress_intf.intf_type;
1142 case INGRESS_INTF_ID: //ingress intf_id
1143 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
1144 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1145 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001146 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 +00001147 return err;
1148 }
1149 return flow_cfg.data.ingress_intf.intf_id;
1150 case EGRESS_INTF_ID: //egress intf_id
1151 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
1152 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1153 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001154 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 +00001155 return err;
1156 }
1157 return flow_cfg.data.egress_intf.intf_id;
1158 case CLASSIFIER_O_VID:
1159 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1160 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1161 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001162 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 +00001163 return err;
1164 }
1165 return flow_cfg.data.classifier.o_vid;
1166 case CLASSIFIER_O_PBITS:
1167 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1168 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1169 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001170 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 +00001171 return err;
1172 }
1173 return flow_cfg.data.classifier.o_pbits;
1174 case CLASSIFIER_I_VID:
1175 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1176 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1177 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001178 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 +00001179 return err;
1180 }
1181 return flow_cfg.data.classifier.i_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001182 case CLASSIFIER_I_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001183 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1184 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1185 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001186 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 +00001187 return err;
1188 }
1189 return flow_cfg.data.classifier.i_pbits;
1190 case CLASSIFIER_ETHER_TYPE:
1191 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1192 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1193 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001194 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 +00001195 return err;
1196 }
1197 return flow_cfg.data.classifier.ether_type;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001198 case CLASSIFIER_IP_PROTO:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001199 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1200 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1201 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001202 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 +00001203 return err;
1204 }
1205 return flow_cfg.data.classifier.ip_proto;
1206 case CLASSIFIER_SRC_PORT:
1207 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1208 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1209 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001210 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 +00001211 return err;
1212 }
1213 return flow_cfg.data.classifier.src_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001214 case CLASSIFIER_DST_PORT:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001215 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1216 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1217 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001218 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 +00001219 return err;
1220 }
1221 return flow_cfg.data.classifier.dst_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001222 case CLASSIFIER_PKT_TAG_TYPE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001223 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1224 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1225 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001226 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 +00001227 return err;
1228 }
1229 return flow_cfg.data.classifier.pkt_tag_type;
1230 case EGRESS_QOS_TYPE:
1231 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
1232 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1233 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001234 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 +00001235 return err;
1236 }
1237 return flow_cfg.data.egress_qos.type;
1238 case EGRESS_QOS_QUEUE_ID:
1239 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
1240 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1241 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001242 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 +00001243 return err;
1244 }
1245 switch (flow_cfg.data.egress_qos.type) {
1246 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE:
1247 return flow_cfg.data.egress_qos.u.fixed_queue.queue_id;
1248 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE:
1249 return flow_cfg.data.egress_qos.u.tc_to_queue.tc_to_queue_id;
1250 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC:
1251 return flow_cfg.data.egress_qos.u.pbit_to_tc.tc_to_queue_id;
1252 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE:
1253 return flow_cfg.data.egress_qos.u.priority_to_queue.tm_q_set_id;
1254 case BCMOLT_EGRESS_QOS_TYPE_NONE:
1255 default:
1256 return -1;
1257 }
1258 case EGRESS_QOS_TM_SCHED_ID:
1259 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
1260 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1261 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001262 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 +00001263 return err;
1264 }
1265 return flow_cfg.data.egress_qos.tm_sched.id;
1266 case ACTION_CMDS_BITMASK:
1267 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1268 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1269 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001270 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 +00001271 return err;
1272 }
1273 return flow_cfg.data.action.cmds_bitmask;
1274 case ACTION_O_VID:
1275 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1276 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1277 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001278 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 +00001279 return err;
1280 }
1281 return flow_cfg.data.action.o_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001282 case ACTION_O_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001283 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1284 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1285 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001286 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 +00001287 return err;
1288 }
1289 return flow_cfg.data.action.o_pbits;
1290 case ACTION_I_VID:
1291 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1292 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1293 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001294 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 +00001295 return err;
1296 }
1297 return flow_cfg.data.action.i_vid;
1298 case ACTION_I_PBITS:
1299 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1300 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1301 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001302 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 +00001303 return err;
1304 }
1305 return flow_cfg.data.action.i_pbits;
1306 case STATE:
1307 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, state);
1308 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1309 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001310 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get state, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001311 return err;
1312 }
1313 return flow_cfg.data.state;
1314 default:
1315 return BCM_ERR_INTERNAL;
1316 }
1317
1318 return err;
1319}
1320
1321Status EnablePonIf_(uint32_t intf_id) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001322 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001323 bcmolt_pon_interface_cfg interface_obj;
1324 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1325 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
1326 bcmolt_interface_state state;
1327
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001328 err = get_pon_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001329 if (err == BCM_ERR_OK) {
1330 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001331 OPENOLT_LOG(WARNING, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001332 return Status::OK;
1333 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001334 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001335 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
1336 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1337 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
1338 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.interval, 5000);
1339 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.onu_post_discovery_mode,
1340 BCMOLT_ONU_POST_DISCOVERY_MODE_ACTIVATE);
1341 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.los, true);
1342 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.onu_alarms, true);
1343 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.tiwi, true);
1344 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.ack_timeout, true);
1345 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.sfi, true);
1346 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.loki, true);
1347 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1348 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1349
1350 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1351 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001352 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 +00001353 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
1354 }
1355 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1356 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001357 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 +00001358 return bcm_to_grpc_err(err, "Failed to enable PON interface");
1359 }
1360 else {
1361 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
1362 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
1363 CreateDefaultSched(intf_id, downstream);
1364 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001365 }
1366
1367 return Status::OK;
1368}
1369
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001370/* Same as bcmolt_cfg_get but with added logic of retrying the API
1371 in case of some specific failures like timeout or object not yet ready
1372*/
1373bcmos_errno bcmolt_cfg_get_mult_retry(bcmolt_oltid olt, bcmolt_cfg *cfg) {
1374 bcmos_errno err;
1375 uint32_t current_try = 0;
1376
1377 while (current_try < MAX_BAL_API_RETRY_COUNT) {
1378 err = bcmolt_cfg_get(olt, cfg);
1379 current_try++;
1380
1381 if (err == BCM_ERR_STATE || err == BCM_ERR_TIMEOUT) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001382 OPENOLT_LOG(WARNING, openolt_log_id, "bcmolt_cfg_get: err = %s\n", bcmos_strerror(err));
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001383 bcmos_usleep(BAL_API_RETRY_TIME_IN_USECS);
1384 continue;
1385 }
1386 else {
1387 break;
1388 }
1389 }
1390
1391 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001392 OPENOLT_LOG(ERROR, openolt_log_id, "bcmolt_cfg_get tried (%d) times with retry time(%d usecs) err = %s\n",
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001393 current_try,
1394 BAL_API_RETRY_TIME_IN_USECS,
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001395 bcmos_strerror(err));
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001396 }
1397 return err;
1398}
1399
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001400Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001401 bcmos_errno err;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001402 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001403 bcmolt_device_key dev_key = { };
1404 bcmolt_olt_cfg olt_cfg = { };
1405 bcmolt_olt_key olt_key = { };
1406 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
1407 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001408
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001409 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
1410 topo.topology_maps.arr = &topo_map[0];
1411 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
1412 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
1413 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001414 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001415 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001416 #ifdef TEST_MODE
1417 // It is impossible to mock the setting of olt_cfg.data.bal_state because
1418 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
1419 // set the olt_cfg.data.topology. So a new stub function is created and address
1420 // of olt_cfg is passed. This is one-of case where we need to test add specific
1421 // code in production code.
1422 err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
1423 #else
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001424 err = bcmolt_cfg_get_mult_retry(dev_id, &olt_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001425 #endif
1426 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001427 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 +00001428 return bcm_to_grpc_err(err, "cfg: Failed to query OLT topology");
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001429 }
1430
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001431 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
1432 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001433
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001434 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
1435 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001436 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001437
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001438 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
1439 num_of_nni_ports,
1440 num_of_pon_ports,
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001441 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001442
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001443 uint32_t num_failed_cfg_gets = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001444 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
1445 dev_key.device_id = devid;
1446 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
1447 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
1448 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
1449 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001450 err = bcmolt_cfg_get_mult_retry(dev_id, &dev_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001451 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001452 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 +00001453 num_failed_cfg_gets++;
1454 continue;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001455 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001456
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001457 std::string bal_version;
1458 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
1459 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
1460 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
1461 firmware_version = "BAL." + bal_version + "__" + firmware_version;
1462
1463 switch(dev_cfg.data.system_mode) {
1464 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
1465 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
1466 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
1467 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
1468 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
1469 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
1470 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
1471 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
1472 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
1473 case 20: board_technology = MIXED_TECH; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,MIXED_TECH); break;
1474 }
1475
1476 switch(dev_cfg.data.chip_family) {
1477 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X_: chip_family = "Maple"; break;
1478 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X_: chip_family = "Aspen"; break;
1479 }
1480
1481 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s object model: %d, family: %s, board_technology: %s\n",
1482 devid, BCM_MAX_PONS_PER_DEV, bal_version.c_str(), BAL_API_VERSION, chip_family.c_str(), board_technology.c_str());
1483
1484 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001485 }
1486
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001487 /* If all the devices returned errors then we tell the caller that this is an error else we work with
1488 only the devices that retured success*/
1489 if (num_failed_cfg_gets == BCM_MAX_DEVS_PER_LINE_CARD) {
1490 OPENOLT_LOG(ERROR, openolt_log_id, "device: Query of all the devices failed\n");
1491 return bcm_to_grpc_err(err, "device: All devices failed query");
1492 }
1493
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001494 return Status::OK;
1495}
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001496#if 0
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001497Status ProbePonIfTechnology_() {
1498 // Probe maximum extent possible as configured into BAL driver to determine
1499 // which are active in the current BAL topology. And for those
1500 // that are active, determine each port's access technology, i.e. "gpon" or "xgspon".
1501 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001502 bcmolt_pon_interface_cfg interface_obj;
1503 bcmolt_pon_interface_key interface_key;
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001504
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001505 interface_key.pon_ni = intf_id;
1506 BCMOLT_CFG_INIT(&interface_obj, pon_interface, interface_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001507 if (board_technology == "XGS-PON"
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001508 BCMOLT_MSG_FIELD_GET(&interface_obj, xgs_ngpon2_trx);
1509 else if (board_technology == "GPON")
1510 BCMOLT_MSG_FIELD_GET(&interface_obj, gpon_trx);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001511
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001512 bcmos_errno err = bcmolt_cfg_get(dev_id, &interface_obj.hdr);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001513 if (err != BCM_ERR_OK) {
Craig Lutgenb2601f02018-10-23 13:04:31 -05001514 intf_technologies[intf_id] = UNKNOWN_TECH;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001515 if(err != BCM_ERR_RANGE) OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get PON config: %d err %d\n", intf_id, err);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001516 }
1517 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001518 if (board_technology == "XGS-PON") {
1519 switch(interface_obj.data.xgpon_trx.transceiver_type) {
1520 case BCMOLT_XGPON_TRX_TYPE_LTH_7222_PC:
1521 case BCMOLT_XGPON_TRX_TYPE_WTD_RTXM266_702:
1522 case BCMOLT_XGPON_TRX_TYPE_LTH_7222_BC_PLUS:
1523 case BCMOLT_XGPON_TRX_TYPE_LTH_7226_PC:
1524 case BCMOLT_XGPON_TRX_TYPE_LTH_5302_PC:
1525 case BCMOLT_XGPON_TRX_TYPE_LTH_7226_A_PC_PLUS:
1526 case BCMOLT_XGPON_TRX_TYPE_D272RR_SSCB_DM:
1527 intf_technologies[intf_id] = "XGS-PON";
1528 break;
1529 }
1530 } else if (board_technology == "GPON") {
1531 switch(interface_obj.data.gpon_trx.transceiver_type) {
1532 case BCMOLT_TRX_TYPE_SPS_43_48_H_HP_CDE_SD_2013:
1533 case BCMOLT_TRX_TYPE_LTE_3680_M:
1534 case BCMOLT_TRX_TYPE_SOURCE_PHOTONICS:
1535 case BCMOLT_TRX_TYPE_LTE_3680_P_TYPE_C_PLUS:
1536 case BCMOLT_TRX_TYPE_LTE_3680_P_BC:
1537 intf_technologies[intf_id] = "GPON";
1538 break;
1539 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001540 }
Craig Lutgenb2601f02018-10-23 13:04:31 -05001541
1542 if (board_technology != UNKNOWN_TECH) {
1543 board_technology = intf_technologies[intf_id];
1544 } else if (board_technology != MIXED_TECH && board_technology != intf_technologies[intf_id]) {
1545 intf_technologies[intf_id] = MIXED_TECH;
1546 }
1547
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001548 }
1549 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001550 return Status::OK;
1551}
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001552#endif
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001553unsigned NumNniIf_() {return num_of_nni_ports;}
1554unsigned NumPonIf_() {return num_of_pon_ports;}
1555
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001556bcmos_errno get_nni_interface_status(bcmolt_interface id, bcmolt_interface_state *state) {
1557 bcmos_errno err;
1558 bcmolt_nni_interface_key nni_key;
1559 bcmolt_nni_interface_cfg nni_cfg;
1560 nni_key.id = id;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001561
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001562 BCMOLT_CFG_INIT(&nni_cfg, nni_interface, nni_key);
1563 BCMOLT_FIELD_SET_PRESENT(&nni_cfg.data, nni_interface_cfg_data, state);
1564 err = bcmolt_cfg_get(dev_id, &nni_cfg.hdr);
1565 *state = nni_cfg.data.state;
1566 return err;
1567}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001568
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001569Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
1570 bcmos_errno err = BCM_ERR_OK;
1571 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
1572 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
1573 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001574
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001575 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001576 if (err == BCM_ERR_OK) {
1577 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001578 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001579 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1580 CreateDefaultSched(intf_id, upstream);
1581 CreateDefaultQueue(intf_id, upstream);
1582 return Status::OK;
1583 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1584 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
1585 return Status::OK;
1586 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001587 }
1588
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001589 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
1590 if (set_state) {
1591 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1592 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1593 } else {
1594 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1595 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1596 }
1597 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
1598 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001599 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err = %s\n",
1600 (set_state)?"enable":"disable", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001601 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
1602 }
1603 else {
1604 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
1605 if (set_state) {
1606 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1607 CreateDefaultSched(intf_id, upstream);
1608 CreateDefaultQueue(intf_id, upstream);
1609 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001610 }
1611
1612 return Status::OK;
1613}
1614
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001615Status DisablePonIf_(uint32_t intf_id) {
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001616 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001617 bcmolt_pon_interface_cfg interface_obj;
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001618 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1619 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001620
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001621 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
1622 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1623 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_DISABLE);
1624
1625 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1626 if (err != BCM_ERR_OK) {
1627 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable discovery of onu, PON interface %d, err %d\n", intf_id, err);
1628 return bcm_to_grpc_err(err, "Failed to disable discovery of onu");
1629 }
1630
1631 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1632 operation, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1633
1634 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1635 if (err != BCM_ERR_OK) {
1636 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 -04001637 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001638 }
1639
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001640 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled PON interface: %d\n", intf_id);
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001641 return Status::OK;
1642}
1643
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001644Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001645 const char *vendor_id, const char *vendor_specific, uint32_t pir) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001646 bcmos_errno err = BCM_ERR_OK;
1647 bcmolt_onu_cfg onu_cfg;
1648 bcmolt_onu_key onu_key;
1649 bcmolt_serial_number serial_number; /**< ONU serial number */
1650 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001651
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001652 onu_key.onu_id = onu_id;
1653 onu_key.pon_ni = intf_id;
1654 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1655 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1656 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001657 if (err == BCM_ERR_OK) {
1658 if ((onu_cfg.data.onu_state == BCMOLT_ONU_STATE_PROCESSING ||
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001659 onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) ||
1660 (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_INACTIVE &&
1661 onu_cfg.data.onu_old_state == BCMOLT_ONU_STATE_NOT_CONFIGURED))
1662 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001663 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001664
1665 OPENOLT_LOG(INFO, openolt_log_id, "Enabling ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001666vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001667 vendor_specific_to_str(vendor_specific).c_str(), pir);
1668
1669 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1670 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1671 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1672 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1673 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1674 /*set burst and data profiles to fec disabled*/
1675 if (board_technology == "XGS-PON") {
1676 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1677 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1678 } else if (board_technology == "GPON") {
1679 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1680 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1681 }
1682 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1683 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001684 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 +00001685 return bcm_to_grpc_err(err, "Failed to activate ONU");
1686 }
1687
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001688 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001689}
1690
Jonathan Davis70c21812018-07-19 15:32:10 -04001691Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1692 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001693 bcmos_errno err = BCM_ERR_OK;
1694 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1695 bcmolt_onu_cfg onu_cfg;
1696 bcmolt_onu_key onu_key; /**< Object key. */
1697 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001698
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001699 onu_key.onu_id = onu_id;
1700 onu_key.pon_ni = intf_id;
1701 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1702 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1703 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001704 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001705 switch (onu_state) {
1706 case BCMOLT_ONU_OPERATION_ACTIVE:
1707 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001708 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001709 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1710 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1711 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001712 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 +00001713 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1714 }
1715 break;
1716 }
Jonathan Davis70c21812018-07-19 15:32:10 -04001717 }
1718
1719 return Status::OK;
1720}
1721
1722Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001723 const char *vendor_id, const char *vendor_specific) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001724
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001725 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 -05001726 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1727
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001728 // Need to deactivate before removing it (BAL rules)
1729
1730 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
1731 // Sleep to allow the state to propagate
1732 // We need the subscriber terminal object to be admin down before removal
1733 // Without sleep the race condition is lost by ~ 20 ms
1734 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1735
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001736 // TODO: Delete the schedulers and queues.
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001737
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001738 bcmolt_onu_cfg cfg_obj;
1739 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001740
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001741 OPENOLT_LOG(INFO, openolt_log_id, "Processing subscriber terminal cfg clear for sub_term_id %d and intf_id %d\n",
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001742 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001743
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001744 key.onu_id = onu_id;
1745 key.pon_ni = intf_id;
1746 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001747
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001748 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001749 if (err != BCM_ERR_OK)
1750 {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001751 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to clear information for BAL subscriber_terminal_id %d, Interface ID %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
Jonathan Davis70c21812018-07-19 15:32:10 -04001752 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1753 }
1754
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001755 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001756}
1757
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001758#define MAX_CHAR_LENGTH 20
1759#define MAX_OMCI_MSG_LENGTH 44
1760Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001761 bcmolt_bin_str buf = {};
1762 bcmolt_onu_cpu_packets omci_cpu_packets;
1763 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001764
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001765 key.pon_ni = intf_id;
1766 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001767
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001768 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1769 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1770 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001771
1772 // ???
1773 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1774 buf.len = MAX_OMCI_MSG_LENGTH;
1775 } else {
1776 buf.len = pkt.size()/2;
1777 }
1778
1779 /* Send the OMCI packet using the BAL remote proxy API */
1780 uint16_t idx1 = 0;
1781 uint16_t idx2 = 0;
1782 uint8_t arraySend[buf.len];
1783 char str1[MAX_CHAR_LENGTH];
1784 char str2[MAX_CHAR_LENGTH];
1785 memset(&arraySend, 0, buf.len);
1786
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001787 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1788 sprintf(str1,"%c", pkt[idx1]);
1789 sprintf(str2,"%c", pkt[++idx1]);
1790 strcat(str1,str2);
1791 arraySend[idx2] = strtol(str1, NULL, 16);
1792 }
1793
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001794 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1795 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001796
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001797 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1798 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1799 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001800
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001801 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001802 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001803 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 +00001804 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001805 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001806 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 -05001807 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001808 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001809 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001810
1811 return Status::OK;
1812}
1813
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001814Status 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 +00001815 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1816 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1817 bcmolt_bin_str buf = {};
1818 bcmolt_gem_port_id gem_port_id_array[1];
1819 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001820
Craig Lutgen967a1d02018-11-27 10:41:51 -06001821 if (port_no > 0) {
1822 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001823 if (gemport_id == 0) {
1824 bcmos_fastlock_lock(&data_lock);
1825 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1826 // Pick any flow that is mapped with the same port_no.
1827 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1828 if (it != port_to_flows.end() && !it->second.empty()) {
1829 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1830 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1831 if (fit != flowid_to_gemport.end()) {
1832 found = true;
1833 gemport_id = fit->second;
1834 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001835 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001836 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001837
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001838 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001839 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 -08001840 onu_id, port_no, intf_id);
1841 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1842 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001843 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 -08001844 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001845 }
1846
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001847 gem_port_id_array[0] = gemport_id;
1848 gem_port_list.len = 1;
1849 gem_port_list.arr = gem_port_id_array;
1850 buf.len = pkt.size();
1851 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1852 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1853
1854 /* init the API struct */
1855 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1856 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1857 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1858 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1859 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1860
1861 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1862 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1863
1864 /* call API */
1865 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001866 }
1867 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001868 //TODO: Port No is 0, it is coming sender requirement.
1869 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1870 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001871 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001872 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001873
1874 return Status::OK;
1875}
1876
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001877Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001878 bcmolt_flow_key key = {}; /* declare key */
1879 bcmolt_bin_str buffer = {};
1880 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001881
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001882 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
1883 bcmolt_flow_id flow_id = 0;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001884
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001885 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1886 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1887 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1888 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1889 key.flow_id = flow_id;
1890 else {
1891 if (flow_id_counters != 0) {
1892 for (int flowid=0; flowid < flow_id_counters; flowid++) {
1893 int flow_index = flow_id_data[flowid][0];
1894 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1895 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1896 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1897 key.flow_id = flow_index;
1898 break;
1899 }
1900 }
1901 }
1902 else {
1903 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1904 }
1905 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001906
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001907 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001908
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001909 /* Initialize the API struct. */
1910 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001911
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001912 buffer.len = pkt.size();
1913 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1914 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1915 if (buffer.arr == NULL) {
1916 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1917 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1918 }
1919 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1920
1921 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1922 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001923 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 Subramani89fffc02019-05-13 21:33:20 +00001924 } else {
1925 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1926 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001927
1928 return Status::OK;
1929}
1930
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001931uint32_t GetPortNum_(uint32_t flow_id) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001932 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001933 uint32_t port_no = 0;
1934 std::map<uint32_t, uint32_t >::const_iterator it = flowid_to_port.find(flow_id);
1935 if (it != flowid_to_port.end()) {
1936 port_no = it->second;
1937 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001938 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001939 return port_no;
1940}
1941
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001942#define FLOW_LOG(level,msg,err) \
1943 do { \
1944 OPENOLT_LOG(level, openolt_log_id, "--------> %s (flow_id %d) err: %d <--------\n", msg, key.flow_id, err); \
1945 OPENOLT_LOG(level, openolt_log_id, "intf_id %d, onu_id %d, uni_id %d, port_no %u, cookie %"PRIu64"\n", \
1946 access_intf_id, onu_id, uni_id, port_no, cookie); \
1947 OPENOLT_LOG(level, openolt_log_id, "flow_type %s, queue_id %d, sched_id %d\n", flow_type.c_str(), \
1948 cfg.data.egress_qos.u.fixed_queue.queue_id, cfg.data.egress_qos.tm_sched.id); \
1949 OPENOLT_LOG(level, openolt_log_id, "Ingress(intfd_type %s, intf_id %d), Egress(intf_type %s, intf_id %d)\n", \
1950 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type), cfg.data.ingress_intf.intf_id, \
1951 GET_FLOW_INTERFACE_TYPE(cfg.data.egress_intf.intf_type), cfg.data.egress_intf.intf_id); \
1952 OPENOLT_LOG(level, openolt_log_id, "classifier(o_vid %d, o_pbits %d, i_vid %d, i_pbits %d, ether type 0x%x)\n", \
1953 c_val.o_vid, c_val.o_pbits, c_val.i_vid, c_val.i_pbits, classifier.eth_type()); \
1954 OPENOLT_LOG(level, openolt_log_id, "classifier(ip_proto 0x%x, gemport_id %d, src_port %d, dst_port %d, pkt_tag_type %s)\n", \
1955 c_val.ip_proto, gemport_id, c_val.src_port, c_val.dst_port, GET_PKT_TAG_TYPE(c_val.pkt_tag_type)); \
1956 OPENOLT_LOG(level, openolt_log_id, "action(cmds_bitmask %s, o_vid %d, o_pbits %d, i_vid %d, i_pbits %d)\n\n", \
1957 get_flow_acton_command(a_val.cmds_bitmask), a_val.o_vid, a_val.o_pbits, a_val.i_vid, a_val.i_pbits); \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001958 } while(0)
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001959
1960#define FLOW_PARAM_LOG() \
1961 do { \
1962 OPENOLT_LOG(INFO, openolt_log_id, "--------> flow comparison (now before) <--------\n"); \
1963 OPENOLT_LOG(INFO, openolt_log_id, "flow_id (%d %d)\n", \
1964 key.flow_id, flow_index); \
1965 OPENOLT_LOG(INFO, openolt_log_id, "onu_id (%d %lu)\n", \
1966 cfg.data.onu_id , get_flow_status(flow_index, flow_id_data[flowid][1], ONU_ID)); \
1967 OPENOLT_LOG(INFO, openolt_log_id, "type (%d %lu)\n", \
1968 key.flow_type, get_flow_status(flow_index, flow_id_data[flowid][1], FLOW_TYPE)); \
1969 OPENOLT_LOG(INFO, openolt_log_id, "svc_port_id (%d %lu)\n", \
1970 cfg.data.svc_port_id, get_flow_status(flow_index, flow_id_data[flowid][1], SVC_PORT_ID)); \
1971 OPENOLT_LOG(INFO, openolt_log_id, "priority (%d %lu)\n", \
1972 cfg.data.priority, get_flow_status(flow_index, flow_id_data[flowid][1], PRIORITY)); \
1973 OPENOLT_LOG(INFO, openolt_log_id, "cookie (%lu %lu)\n", \
1974 cfg.data.cookie, get_flow_status(flow_index, flow_id_data[flowid][1], COOKIE)); \
1975 OPENOLT_LOG(INFO, openolt_log_id, "ingress intf_type (%s %s)\n", \
1976 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type), \
1977 GET_FLOW_INTERFACE_TYPE(get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_TYPE))); \
1978 OPENOLT_LOG(INFO, openolt_log_id, "ingress intf id (%d %lu)\n", \
1979 cfg.data.ingress_intf.intf_id , get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_ID)); \
1980 OPENOLT_LOG(INFO, openolt_log_id, "egress intf_type (%d %lu)\n", \
1981 cfg.data.egress_intf.intf_type , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_TYPE)); \
1982 OPENOLT_LOG(INFO, openolt_log_id, "egress intf_id (%d %lu)\n", \
1983 cfg.data.egress_intf.intf_id , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_ID)); \
1984 OPENOLT_LOG(INFO, openolt_log_id, "classifier o_vid (%d %lu)\n", \
1985 c_val.o_vid , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_VID)); \
1986 OPENOLT_LOG(INFO, openolt_log_id, "classifier o_pbits (%d %lu)\n", \
1987 c_val.o_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_PBITS)); \
1988 OPENOLT_LOG(INFO, openolt_log_id, "classifier i_vid (%d %lu)\n", \
1989 c_val.i_vid , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_VID)); \
1990 OPENOLT_LOG(INFO, openolt_log_id, "classifier i_pbits (%d %lu)\n", \
1991 c_val.i_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_PBITS)); \
1992 OPENOLT_LOG(INFO, openolt_log_id, "classifier ether_type (0x%x 0x%lx)\n", \
1993 c_val.ether_type , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_ETHER_TYPE)); \
1994 OPENOLT_LOG(INFO, openolt_log_id, "classifier ip_proto (%d %lu)\n", \
1995 c_val.ip_proto , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_IP_PROTO)); \
1996 OPENOLT_LOG(INFO, openolt_log_id, "classifier src_port (%d %lu)\n", \
1997 c_val.src_port , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_SRC_PORT)); \
1998 OPENOLT_LOG(INFO, openolt_log_id, "classifier dst_port (%d %lu)\n", \
1999 c_val.dst_port , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_DST_PORT)); \
2000 OPENOLT_LOG(INFO, openolt_log_id, "classifier pkt_tag_type (%s %s)\n", \
2001 GET_PKT_TAG_TYPE(c_val.pkt_tag_type), \
2002 GET_PKT_TAG_TYPE(get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_PKT_TAG_TYPE))); \
2003 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos type (%d %lu)\n", \
2004 cfg.data.egress_qos.type , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TYPE)); \
2005 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos queue_id (%d %lu)\n", \
2006 cfg.data.egress_qos.u.fixed_queue.queue_id, \
2007 get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_QUEUE_ID)); \
2008 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos sched_id (%d %lu)\n", \
2009 cfg.data.egress_qos.tm_sched.id, \
2010 get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TM_SCHED_ID)); \
2011 OPENOLT_LOG(INFO, openolt_log_id, "classifier cmds_bitmask (%s %s)\n", \
2012 get_flow_acton_command(a_val.cmds_bitmask), \
2013 get_flow_acton_command(get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_CMDS_BITMASK))); \
2014 OPENOLT_LOG(INFO, openolt_log_id, "action o_vid (%d %lu)\n", \
2015 a_val.o_vid , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_VID)); \
2016 OPENOLT_LOG(INFO, openolt_log_id, "action i_vid (%d %lu)\n", \
2017 a_val.i_vid , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_VID)); \
2018 OPENOLT_LOG(INFO, openolt_log_id, "action o_pbits (%d %lu)\n", \
2019 a_val.o_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_PBITS)); \
2020 OPENOLT_LOG(INFO, openolt_log_id, "action i_pbits (%d %lu)\n\n", \
2021 a_val.i_pbits, get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_PBITS)); \
2022 } while(0)
2023
2024#define FLOW_CHECKER
2025//#define SHOW_FLOW_PARAM
2026
Craig Lutgen967a1d02018-11-27 10:41:51 -06002027Status 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 +00002028 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002029 int32_t alloc_id, int32_t network_intf_id,
2030 int32_t gemport_id, const ::openolt::Classifier& classifier,
Craig Lutgen967a1d02018-11-27 10:41:51 -06002031 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002032 bcmolt_flow_cfg cfg;
2033 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002034 int32_t o_vid = -1;
2035 bool single_tag = false;
2036 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002037 bcmolt_classifier c_val = { };
2038 bcmolt_action a_val = { };
2039 bcmolt_tm_queue_ref tm_val = { };
2040 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002041 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002042
2043 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002044 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002045 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002046 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002047 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002048 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002049 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04002050 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002051 }
2052
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002053 BCMOLT_CFG_INIT(&cfg, flow, key);
2054 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002055
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002056 if (access_intf_id >= 0 && network_intf_id >= 0) {
2057 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
2058 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
2059 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
2060 if (classifier.eth_type() == EAP_ETHER_TYPE || //EAPOL packet
2061 (classifier.ip_proto() == 17 && classifier.src_port() == 68 && classifier.dst_port() == 67)) { //DHCP packet
2062 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_HOST);
2063 } else {
2064 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
2065 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
2066 }
2067 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
2068 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
2069 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
2070 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
2071 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
2072 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302073 } else if (access_intf_id < 0 ) {
2074 // This is the case for packet trap from NNI flow.
2075 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
2076 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
2077 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_HOST);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002078 } else {
2079 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
2080 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
2081 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002082
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302083
Shad Ansari39739bc2018-09-13 21:38:37 +00002084 if (onu_id >= 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002085 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00002086 }
2087 if (gemport_id >= 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002088 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00002089 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002090 if (gemport_id >= 0 && port_no != 0) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002091 bcmos_fastlock_lock(&data_lock);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002092 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002093 port_to_flows[port_no].insert(key.flow_id);
2094 flowid_to_gemport[key.flow_id] = gemport_id;
2095 }
2096 else
2097 {
2098 flowid_to_port[key.flow_id] = port_no;
2099 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002100 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002101 }
Shad Ansari39739bc2018-09-13 21:38:37 +00002102 if (priority_value >= 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002103 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
Shad Ansari39739bc2018-09-13 21:38:37 +00002104 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002105
2106 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002107 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002108 if (classifier.o_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002109 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_tpid 0x%04x\n", classifier.o_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002110 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, o_tpid, classifier.o_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002111 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002112 */
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002113 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002114 if (classifier.i_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002115 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_tpid 0x%04x\n", classifier.i_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002116 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, i_tpid, classifier.i_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002117 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002118 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002119
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002120 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002121 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002122 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
2123 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002124 }
2125
2126 /*
2127 if (classifier.dst_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002128 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_mac, classifier.dst_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002129 }
2130
2131 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002132 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002133 }
2134 */
2135
2136 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002137 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
2138 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002139 }
2140
2141 /*
2142 if (classifier.dst_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002143 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_ip, classifier.dst_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002144 }
2145
2146 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002147 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002148 }
2149 */
2150
2151 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002152 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
2153 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002154 }
2155
2156 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002157 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
2158 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002159 }
2160
2161 if (!classifier.pkt_tag_type().empty()) {
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302162 if (cfg.data.ingress_intf.intf_type == BCMOLT_FLOW_INTERFACE_TYPE_NNI && \
2163 cfg.data.egress_intf.intf_type == BCMOLT_FLOW_INTERFACE_TYPE_HOST) {
2164 // This is case where packet traps from NNI port. As per Broadcom workaround
2165 // suggested in CS8839882, the packet_tag_type has to be 'untagged' irrespective
2166 // of what the actual tag type is. Otherwise, packet trap from NNI wont work.
2167 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
2168 } else {
2169 if (classifier.o_vid()) {
2170 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
2171 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
2172 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002173
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302174 if (classifier.i_vid()) {
2175 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
2176 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
2177 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002178
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302179 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
2180 if (classifier.pkt_tag_type().compare("untagged") == 0) {
2181 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
2182 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
2183 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
2184 single_tag = true;
2185
2186 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
YJbbeeff42019-11-21 16:22:50 -05002187 if(classifier.o_pbits()){
2188 //According to makeOpenOltClassifierField in voltha-openolt-adapter, o_pbits 0xFF means PCP value 0.
2189 //0 vlaue of o_pbits means o_pbits is not available
2190 if(0xFF == classifier.o_pbits()){
2191 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, 0);
2192 }
2193 else{
2194 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
2195 }
2196 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302197 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
2198 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
2199
2200 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
YJbbeeff42019-11-21 16:22:50 -05002201 if(classifier.o_pbits()){
2202 if(0xFF == classifier.o_pbits()){
2203 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, 0);
2204 }
2205 else{
2206 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
2207 }
2208 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302209 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002210 }
2211 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002212 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002213 }
2214
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002215 if (cfg.data.egress_intf.intf_type != BCMOLT_FLOW_INTERFACE_TYPE_HOST) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002216 const ::openolt::ActionCmd& cmd = action.cmd();
2217
2218 if (cmd.add_outer_tag()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002219 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
2220 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002221 }
2222
2223 if (cmd.remove_outer_tag()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002224 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
2225 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002226 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002227 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002228 if (cmd.trap_to_host()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002229 OPENOLT_LOG(INFO, openolt_log_id, "action trap-to-host\n");
Craig Lutgen19512312018-11-02 10:14:46 -05002230 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, cmds_bitmask, BCMBAL_ACTION_CMD_ID_TRAP_TO_HOST);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002231 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002232 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002233 if (action.o_vid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002234 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002235 o_vid = action.o_vid();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002236 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002237 }
2238
2239 if (action.o_pbits()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002240 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
2241 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002242 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002243 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002244 if (action.o_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002245 OPENOLT_LOG(INFO, openolt_log_id, "action o_tpid=0x%04x\n", action.o_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002246 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, o_tpid, action.o_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002247 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002248 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002249 if (action.i_vid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002250 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
2251 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002252 }
2253
2254 if (action.i_pbits()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002255 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
2256 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002257 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002258 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002259 if (action.i_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002260 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_tpid=0x%04x\n", action.i_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002261 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, i_tpid, action.i_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002262 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002263 */
2264 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002265 }
2266
Shad Ansari39739bc2018-09-13 21:38:37 +00002267 if ((access_intf_id >= 0) && (onu_id >= 0)) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002268 if(single_tag && ether_type == EAP_ETHER_TYPE) {
2269 tm_val.sched_id = (flow_type.compare(upstream) == 0) ? \
2270 get_default_tm_sched_id(network_intf_id, upstream) : \
2271 get_default_tm_sched_id(access_intf_id, downstream);
2272 tm_val.queue_id = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002273
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002274 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2275 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2276 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002277
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002278 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2279 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
2280 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2281 } else {
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002282 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002283 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
2284 tm_val.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, downstream);
2285
2286 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2287 // Queue 0 on DS subscriber scheduler
2288 tm_val.queue_id = 0;
2289
2290 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2291 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2292 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2293
2294 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2295 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2296 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2297
2298 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2299 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
2300 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2301
2302 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2303 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2304 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2305 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_q_set_id, tm_q_set_id);
2306
2307 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2308 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2309 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2310 }
2311 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
2312 // NNI Scheduler ID
2313 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2314 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2315 // Queue 0 on NNI scheduler
2316 tm_val.queue_id = 0;
2317 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2318 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2319 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2320
2321 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2322 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2323 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2324
2325 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2326 /* Fetch TM QMP ID mapped to US NNI scheduler */
2327 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2328 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2329 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2330 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2331 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_q_set_id, tm_q_set_id);
2332
2333 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2334 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2335 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2336 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002337 }
Shad Ansari39739bc2018-09-13 21:38:37 +00002338 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302339 } else {
2340 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2341 tm_val.queue_id = 0;
2342
2343 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2344 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2345 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2346
2347 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2348 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
2349 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00002350 }
2351
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002352 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
2353 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
2354#ifdef FLOW_CHECKER
2355 //Flow Checker, To avoid duplicate flow.
2356 if (flow_id_counters != 0) {
2357 bool b_duplicate_flow = false;
2358 for (int flowid=0; flowid < flow_id_counters; flowid++) {
2359 int flow_index = flow_id_data[flowid][0];
2360 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(flow_index, flow_id_data[flowid][1], ONU_ID)) && \
2361 (key.flow_type == flow_id_data[flowid][1]) && \
2362 (cfg.data.svc_port_id == get_flow_status(flow_index, flow_id_data[flowid][1], SVC_PORT_ID)) && \
2363 (cfg.data.priority == get_flow_status(flow_index, flow_id_data[flowid][1], PRIORITY)) && \
2364 (cfg.data.cookie == get_flow_status(flow_index, flow_id_data[flowid][1], COOKIE)) && \
2365 (cfg.data.ingress_intf.intf_type == get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_TYPE)) && \
2366 (cfg.data.ingress_intf.intf_id == get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_ID)) && \
2367 (cfg.data.egress_intf.intf_type == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_TYPE)) && \
2368 (cfg.data.egress_intf.intf_id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_ID)) && \
2369 (c_val.o_vid == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_VID)) && \
2370 (c_val.o_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_PBITS)) && \
2371 (c_val.i_vid == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_VID)) && \
2372 (c_val.i_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_PBITS)) && \
2373 (c_val.ether_type == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_ETHER_TYPE)) && \
2374 (c_val.ip_proto == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_IP_PROTO)) && \
2375 (c_val.src_port == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_SRC_PORT)) && \
2376 (c_val.dst_port == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_DST_PORT)) && \
2377 (c_val.pkt_tag_type == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_PKT_TAG_TYPE)) && \
2378 (cfg.data.egress_qos.type == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TYPE)) && \
2379 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_QUEUE_ID)) && \
2380 (cfg.data.egress_qos.tm_sched.id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TM_SCHED_ID)) && \
2381 (a_val.cmds_bitmask == get_flow_status(flowid, flow_id_data[flowid][1], ACTION_CMDS_BITMASK)) && \
2382 (a_val.o_vid == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_VID)) && \
2383 (a_val.i_vid == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_VID)) && \
2384 (a_val.o_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_PBITS)) && \
2385 (a_val.i_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_PBITS)) && \
2386 (cfg.data.state == get_flow_status(flowid, flow_id_data[flowid][1], STATE));
2387#ifdef SHOW_FLOW_PARAM
2388 // Flow Parameter
2389 FLOW_PARAM_LOG();
2390#endif
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002391
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002392 if (b_duplicate_flow) {
2393 FLOW_LOG(WARNING, "Flow duplicate", 0);
2394 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
2395 }
2396 }
2397 }
2398#endif
2399
2400 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2401 if (err) {
2402 FLOW_LOG(ERROR, "Flow add failed", err);
2403 return bcm_to_grpc_err(err, "flow add failed");
2404 } else {
2405 FLOW_LOG(INFO, "Flow add ok", err);
2406 bcmos_fastlock_lock(&data_lock);
2407 flow_id_data[flow_id_counters][0] = key.flow_id;
2408 flow_id_data[flow_id_counters][1] = key.flow_type;
2409 flow_id_counters += 1;
2410 bcmos_fastlock_unlock(&data_lock, 0);
2411 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04002412
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002413 return Status::OK;
2414}
2415
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002416Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
2417
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002418 bcmolt_flow_cfg cfg;
2419 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002420
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002421 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002422 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002423 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002424 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002425 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002426 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002427 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002428 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002429 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
2430 }
2431
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002432 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002433 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002434 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002435 flowid_to_gemport.erase(key.flow_id);
2436 port_to_flows[port_no].erase(key.flow_id);
2437 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
2438 }
2439 else
2440 {
2441 flowid_to_port.erase(key.flow_id);
2442 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002443 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002444
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002445 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002446
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002447 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002448 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002449 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 -04002450 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
2451 }
2452
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002453 bcmos_fastlock_lock(&data_lock);
2454 for (int flowid=0; flowid < flow_id_counters; flowid++) {
2455 if (flow_id_data[flowid][0] == flow_id && flow_id_data[flowid][1] == key.flow_type) {
2456 flow_id_counters -= 1;
2457 for (int i=flowid; i < flow_id_counters; i++) {
2458 flow_id_data[i][0] = flow_id_data[i + 1][0];
2459 flow_id_data[i][1] = flow_id_data[i + 1][1];
2460 }
2461 break;
2462 }
2463 }
2464 bcmos_fastlock_unlock(&data_lock, 0);
2465
2466 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002467 return Status::OK;
2468}
2469
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002470bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
2471 bcmos_errno err;
2472 bcmolt_tm_sched_cfg tm_sched_cfg;
2473 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2474 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
2475
Jason Huangbf45ffb2019-10-30 17:29:02 +08002476 //check TM scheduler has configured or not
2477 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2478 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
2479 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
2480 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002481 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 +08002482 return err;
2483 }
2484 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
2485 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
2486 return BCM_ERR_OK;
2487 }
2488
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002489 // bcmbal_tm_sched_owner
2490 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2491
2492 /**< The output of the tm_sched object instance */
2493 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
2494
2495 if (direction.compare(upstream) == 0) {
2496 // In upstream it is NNI scheduler
2497 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
2498 } else if (direction.compare(downstream) == 0) {
2499 // In downstream it is PON scheduler
2500 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2501 }
2502
2503 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2504
2505 // bcmbal_tm_sched_type
2506 // set the deafult policy to strict priority
2507 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2508
2509 // num_priorities: Max number of strict priority scheduling elements
2510 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
2511
2512 // bcmbal_tm_shaping
2513 uint32_t cir = 1000000;
2514 uint32_t pir = 1000000;
2515 uint32_t burst = 65536;
2516 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in %s pir=%u, burst=%u\n",
2517 direction.c_str(), pir, burst);
2518 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2519 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2520 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2521 // BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2522 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2523 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
2524
2525 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2526 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002527 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
2528 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002529 return err;
2530 }
2531
2532 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2533 direction.c_str(), tm_sched_key.id, intf_id);
2534 return BCM_ERR_OK;
2535}
2536
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002537bcmos_errno CreateSched(std::string direction, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t port_no,
2538 uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
2539 tech_profile::SchedulingPolicy sched_policy, tech_profile::TrafficShapingInfo tf_sh_info) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002540
2541 bcmos_errno err;
2542
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002543 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002544 bcmolt_tm_sched_cfg tm_sched_cfg;
2545 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2546 tm_sched_key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002547
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002548 // bcmbal_tm_sched_owner
2549 // In downstream it is sub_term scheduler
2550 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002551
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002552 /**< The output of the tm_sched object instance */
2553 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002554
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002555 // bcmbal_tm_sched_parent
2556 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2557 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
2558 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_param.u.priority.priority, priority);
2559 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
2560 be achieved using the' virtual' type of attachment.
2561 tm_sched_owner.u.sub_term.intf_id = intf_id;
2562 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2563 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002564
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002565 // bcmbal_tm_sched_type
2566 // set the deafult policy to strict priority
2567 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002568
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002569 // num_priorities: Max number of strict priority scheduling elements
2570 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002571
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002572 // bcmbal_tm_shaping
2573 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2574 uint32_t cir = tf_sh_info.cir();
2575 uint32_t pir = tf_sh_info.pir();
2576 uint32_t burst = tf_sh_info.pbs();
2577 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2578 cir, pir, burst);
2579 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2580 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2581 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2582 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2583 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2584 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002585 }
2586
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002587 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002588 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002589 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002590intf_id %d, onu_id %d, uni_id %d, port_no %u, err = %s\n", tm_sched_key.id, intf_id, onu_id, uni_id, \
2591port_no, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002592 return err;
2593 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002594 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2595uni_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 -08002596
2597 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002598 bcmolt_itupon_alloc_cfg cfg;
2599 bcmolt_itupon_alloc_key key = { };
2600 key.pon_ni = intf_id;
2601 key.alloc_id = alloc_id;
2602 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
2603 int pir_bw = tf_sh_info.pir();
2604 int cir_bw = tf_sh_info.cir();
2605 //offset to match bandwidth granularity
2606 int offset_pir_bw = pir_bw%bw_granularity;
2607 int offset_cir_bw = cir_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002608
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002609 pir_bw = pir_bw - offset_pir_bw;
2610 cir_bw = cir_bw - offset_cir_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002611
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002612 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002613
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002614 switch (additional_bw) {
2615 case 2: //AdditionalBW_BestEffort
2616 if (pir_bw == 0) {
2617 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2618%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2619 } else if (pir_bw < cir_bw) {
2620 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2621bandwidth (%d)\n", pir_bw, cir_bw);
2622 return BCM_ERR_PARM;
2623 } else if (pir_bw == cir_bw) {
2624 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2625bandwidth for additional bandwidth eligibility of type best_effort\n");
2626 return BCM_ERR_PARM;
2627 }
2628 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2629 break;
2630 case 1: //AdditionalBW_NA
2631 if (pir_bw == 0) {
2632 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2633%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2634 return BCM_ERR_PARM;
2635 } else if (cir_bw == 0) {
2636 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2637additional bandwidth eligibility of type Non-Assured (NA)\n");
2638 return BCM_ERR_PARM;
2639 } else if (pir_bw < cir_bw) {
2640 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2641bandwidth (%d)\n", pir_bw, cir_bw);
2642 return BCM_ERR_PARM;
2643 } else if (pir_bw == cir_bw) {
2644 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2645bandwidth for additional bandwidth eligibility of type non_assured\n");
2646 return BCM_ERR_PARM;
2647 }
2648 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2649 break;
2650 case 0: //AdditionalBW_None
2651 if (pir_bw == 0) {
2652 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
265316000 bytes/sec\n");
2654 return BCM_ERR_PARM;
2655 } else if (cir_bw == 0) {
2656 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2657for additional bandwidth eligibility of type None\n");
2658 return BCM_ERR_PARM;
2659 } else if (pir_bw > cir_bw) {
2660 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2661for additional bandwidth eligibility of type None\n");
2662 OPENOLT_LOG(ERROR, openolt_log_id, "set Maximum bandwidth (%d) to Guaranteed \
2663bandwidth in None eligibility\n", pir_bw);
2664 cir_bw = pir_bw;
2665 } else if (pir_bw < cir_bw) {
2666 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2667bandwidth (%d)\n", pir_bw, cir_bw);
2668 OPENOLT_LOG(ERROR, openolt_log_id, "set Maximum bandwidth (%d) to Guaranteed \
2669bandwidth in None eligibility\n", pir_bw);
2670 cir_bw = pir_bw;
2671 }
2672 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2673 break;
2674 default:
2675 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002676 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002677 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2678 in a fine granularity. */
2679 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
2680 /* Fixed Bandwidth with no critical requirement of shaping */
2681 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, 0);
2682 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
2683 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, cir_bw);
2684 /* Maximum allocated bandwidth allowed for this alloc ID */
2685 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
2686 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
2687 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
2688 for skipped allocations during quiet window */
2689 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2690 /**< Allocation Profile index for CBR non-RT Bandwidth */
2691 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2692 /**< Allocation Profile index for CBR RT Bandwidth */
2693 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2694 /**< Alloc ID Weight used in case of Extended DBA mode */
2695 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2696 /**< Alloc ID Priority used in case of Extended DBA mode */
2697 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2698 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002699
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002700 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002701 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002702 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 -05002703port_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 -08002704 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002705 }
Girish Gowdra96461052019-11-22 20:13:59 +05302706
2707 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
2708 if (err) {
2709 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2710port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
2711 return err;
2712 }
2713
2714 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
2715port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
2716
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002717 }
2718
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002719 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002720}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002721
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002722Status CreateTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2723 uint32_t intf_id = traffic_scheds->intf_id();
2724 uint32_t onu_id = traffic_scheds->onu_id();
2725 uint32_t uni_id = traffic_scheds->uni_id();
2726 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002727 std::string direction;
2728 unsigned int alloc_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002729 tech_profile::SchedulerConfig sched_config;
2730 tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002731 uint32_t priority;
2732 uint32_t weight;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002733 tech_profile::SchedulingPolicy sched_policy;
2734 tech_profile::TrafficShapingInfo traffic_shaping_info;
2735 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002736
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002737 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2738 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002739
2740 direction = GetDirection(traffic_sched.direction());
2741 if (direction.compare("direction-not-supported") == 0)
2742 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2743
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002744 alloc_id = traffic_sched.alloc_id();
2745 sched_config = traffic_sched.scheduler();
2746 additional_bw = sched_config.additional_bw();
2747 priority = sched_config.priority();
2748 weight = sched_config.weight();
2749 sched_policy = sched_config.sched_policy();
2750 traffic_shaping_info = traffic_sched.traffic_shaping_info();
2751 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
2752 sched_policy, traffic_shaping_info);
2753 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002754 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002755 return bcm_to_grpc_err(err, "Failed to create scheduler");
2756 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002757 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002758 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002759}
Jonathan Davis70c21812018-07-19 15:32:10 -04002760
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002761bcmos_errno RemoveSched(int intf_id, int onu_id, int uni_id, int alloc_id, std::string direction) {
Jonathan Davis70c21812018-07-19 15:32:10 -04002762
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002763 bcmos_errno err;
Girish Gowdra96461052019-11-22 20:13:59 +05302764 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002765
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002766 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002767 bcmolt_itupon_alloc_cfg cfg;
2768 bcmolt_itupon_alloc_key key = { };
2769 key.pon_ni = intf_id;
2770 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302771 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002772
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002773 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
2774 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2775 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002776 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2777 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002778 return err;
2779 }
Girish Gowdra96461052019-11-22 20:13:59 +05302780
2781 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2782 if (err) {
2783 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2784 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
2785 return err;
2786 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002787 } else if (direction == downstream) {
2788 bcmolt_tm_sched_cfg cfg;
2789 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002790
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002791 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction)) {
2792 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
Girish Gowdra96461052019-11-22 20:13:59 +05302793 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002794 } else {
2795 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2796 return BCM_ERR_OK;
2797 }
Girish Gowdra96461052019-11-22 20:13:59 +05302798
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002799 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2800 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2801 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002802 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
2803intf_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 +00002804 return err;
2805 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002806 }
2807
Girish Gowdra96461052019-11-22 20:13:59 +05302808 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d\n",
2809 direction.c_str(), sched_id, intf_id, onu_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002810 free_tm_sched_id(intf_id, onu_id, uni_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002811 return BCM_ERR_OK;
2812}
2813
2814Status RemoveTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2815 uint32_t intf_id = traffic_scheds->intf_id();
2816 uint32_t onu_id = traffic_scheds->onu_id();
2817 uint32_t uni_id = traffic_scheds->uni_id();
2818 std::string direction;
2819 bcmos_errno err;
2820
2821 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2822 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002823
2824 direction = GetDirection(traffic_sched.direction());
2825 if (direction.compare("direction-not-supported") == 0)
2826 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2827
2828 int alloc_id = traffic_sched.alloc_id();
2829 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002830 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002831 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002832 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2833 }
2834 }
2835 return Status::OK;
2836}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002837
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002838bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2839 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002840 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002841 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2842 bcmolt_tm_qmp_key tm_qmp_key;
2843 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002844
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002845 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2846 if (tm_qmp_id == -1) {
2847 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed profile count is 16.\n");
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002848 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002849
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002850 tm_qmp_key.id = tm_qmp_id;
2851 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2852 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2853 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002854
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002855 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2856 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2857 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
2858 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2859 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002860
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002861 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002862 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002863 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2864 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002865 return err;
2866 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002867
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002868 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2869 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002870 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002871}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002872
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002873bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2874 bcmos_errno err;
2875 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2876 bcmolt_tm_qmp_key tm_qmp_key;
2877 tm_qmp_key.id = tm_qmp_id;
2878
2879 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2880 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2881 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002882 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2883 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002884 return err;
2885 }
2886
2887 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2888 tm_qmp_key.id);
2889 return BCM_ERR_OK;
2890}
2891
2892bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2893 bcmos_errno err;
2894
2895 /* Create 4 Queues on given PON/NNI scheduler */
2896 for (int queue_id = 0; queue_id < 4; queue_id++) {
2897 bcmolt_tm_queue_cfg tm_queue_cfg;
2898 bcmolt_tm_queue_key tm_queue_key = {};
2899 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2900 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002901 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2902 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2903 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002904
2905 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2906 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2907 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2908
2909 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2910 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002911 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", \
2912 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 +00002913 return err;
2914 }
2915
2916 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2917 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2918 }
2919 return BCM_ERR_OK;
2920}
2921
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002922bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
2923 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002924 bcmos_errno err;
2925 bcmolt_tm_queue_cfg cfg;
2926 bcmolt_tm_queue_key key = { };
2927 OPENOLT_LOG(INFO, openolt_log_id, "creating %s queue. access_intf_id = %d, onu_id = %d, uni_id = %d \
2928gemport_id = %d\n", direction.c_str(), access_intf_id, onu_id, uni_id, gemport_id);
2929
2930 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2931 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
2932
2933 if (priority > 7) {
2934 return BCM_ERR_RANGE;
2935 }
2936
2937 /* FIXME: The upstream queues have to be created once only.
2938 The upstream queues on the NNI scheduler are shared by all subscribers.
2939 When the first scheduler comes in, the queues get created, and are re-used by all others.
2940 Also, these queues should be present until the last subscriber exits the system.
2941 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2942
2943 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2944 for each GEM in TECH PROFILE */
2945 key.id = queue_id_list[priority];
2946
2947 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2948 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2949 key.id = 0;
2950 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2951 }
2952 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2953 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2954 }
2955 else {
2956 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2957 }
2958
2959 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2960
2961 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2962 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
2963
2964 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2965 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002966 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
2967sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n", \
2968 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 +00002969 return err;
2970 }
2971
2972 OPENOLT_LOG(INFO, openolt_log_id, "Created tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2973intf_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);
2974 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002975}
2976
2977Status CreateTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2978 uint32_t intf_id = traffic_queues->intf_id();
2979 uint32_t onu_id = traffic_queues->onu_id();
2980 uint32_t uni_id = traffic_queues->uni_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002981 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002982 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002983 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002984 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 +00002985
2986 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2987 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2988 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2989 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2990 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
2991
2992 direction = GetDirection(traffic_queue.direction());
2993 if (direction.compare("direction-not-supported") == 0)
2994 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2995
2996 queues_priority_q[i] = traffic_queue.priority();
2997 queues_pbit_map[i] = traffic_queue.pbit_map();
2998 }
2999
3000 std::vector<uint32_t> tmq_map_profile(8, 0);
3001 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
3002 queues_priority_q, COUNT_OF(queues_priority_q));
3003 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
3004 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
3005
3006 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
3007 if (tm_qmp_id == -1) {
3008 CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
3009 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
3010 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
3011 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
3012 }
3013 }
3014
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003015 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
3016 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003017
3018 direction = GetDirection(traffic_queue.direction());
3019 if (direction.compare("direction-not-supported") == 0)
3020 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
3021
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003022 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 +00003023
Girish Gowdruf26cf882019-05-01 23:47:58 -07003024 // If the queue exists already, lets not return failure and break the loop.
3025 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003026 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003027 return bcm_to_grpc_err(err, "Failed to create queue");
3028 }
3029 }
3030 return Status::OK;
3031}
3032
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003033bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
3034 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003035 bcmolt_tm_queue_cfg cfg;
3036 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003037 bcmos_errno err;
3038
3039 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003040 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction)) {
3041 key.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
3042 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003043 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003044 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 -08003045 return BCM_ERR_OK;
3046 }
3047 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003048 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
3049 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003050 return BCM_ERR_OK;
3051 }
3052
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003053 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
3054 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
3055 // Reset the queue id to 0 when using fixed queue.
3056 key.id = 0;
3057 }
3058 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
3059 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
3060 }
3061 else {
3062 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
3063 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003064
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003065 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
3066 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003067 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003068 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, queue_id %d, sched_id %d, \
3069tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n",
3070 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 -08003071 return err;
3072 }
3073
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003074 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
3075intf_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 -08003076
3077 return BCM_ERR_OK;
3078}
3079
3080Status RemoveTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
3081 uint32_t intf_id = traffic_queues->intf_id();
3082 uint32_t onu_id = traffic_queues->onu_id();
3083 uint32_t uni_id = traffic_queues->uni_id();
3084 uint32_t port_no = traffic_queues->port_no();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003085 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003086 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003087 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003088 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 +00003089
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003090 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
3091 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003092
3093 direction = GetDirection(traffic_queue.direction());
3094 if (direction.compare("direction-not-supported") == 0)
3095 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
3096
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003097 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 -08003098 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003099 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003100 return bcm_to_grpc_err(err, "Failed to remove queue");
3101 }
Jonathan Davis70c21812018-07-19 15:32:10 -04003102 }
3103
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003104 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))) {
3105 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
3106 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
3107
3108 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
3109 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
3110 RemoveTrafficQueueMappingProfile(tm_qmp_id);
3111 }
3112 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003113 clear_qos_type(intf_id, onu_id, uni_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04003114 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04003115}
Jason Huangbf45ffb2019-10-30 17:29:02 +08003116
3117Status check_connection() {
3118 int maxTrials = 60;
3119 while (!bcmolt_api_conn_mgr_is_connected(dev_id)) {
3120 sleep(1);
3121 if (--maxTrials == 0)
3122 return grpc::Status(grpc::StatusCode::UNAVAILABLE, "check connection failed");
3123 else
3124 OPENOLT_LOG(INFO, openolt_log_id, "waiting for daemon connection ...\n");
3125 }
3126 OPENOLT_LOG(INFO, openolt_log_id, "daemon is connected\n");
3127 return Status::OK;
3128}
3129
3130Status check_bal_ready() {
3131 bcmos_errno err;
3132 int maxTrials = 30;
3133 bcmolt_olt_cfg olt_cfg = { };
3134 bcmolt_olt_key olt_key = { };
3135
3136 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
3137 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
3138
3139 while (olt_cfg.data.bal_state != BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY) {
3140 if (--maxTrials == 0)
3141 return grpc::Status(grpc::StatusCode::UNAVAILABLE, "check bal ready failed");
3142 sleep(5);
3143 #ifdef TEST_MODE
3144 // It is impossible to mock the setting of olt_cfg.data.bal_state because
3145 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
3146 // set the olt_cfg.data.bal_state. So a new stub function is created and address
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04003147 // of olt_cfg is passed. This is one-of case where we need to add test specific
3148 // code in production code.
3149 if (bcmolt_cfg_get__bal_state_stub(dev_id, &olt_cfg)) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08003150 #else
3151 if (bcmolt_cfg_get(dev_id, &olt_cfg.hdr)) {
3152 #endif
3153 continue;
3154 }
3155 else
3156 OPENOLT_LOG(INFO, openolt_log_id, "waiting for BAL ready ...\n");
3157 }
3158
3159 OPENOLT_LOG(INFO, openolt_log_id, "BAL is ready\n");
3160 return Status::OK;
3161}