blob: ef92547f1edb20e135d897ba74f4fc3343cc4a4b [file] [log] [blame]
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001/*
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04002 Copyright (C) 2018 Open Networking Foundation
Shad Ansarib7b0ced2018-05-11 21:53:32 +00003
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#include <iostream>
19#include <memory>
20#include <string>
21
22#include "Queue.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000023#include <sstream>
Nicolas Palpacuer9c352082018-08-14 16:37:14 -040024#include <chrono>
25#include <thread>
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080026#include <bitset>
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000027#include <inttypes.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
106/* Current session */
107static bcmcli_session *current_session;
108static bcmcli_entry *api_parent_dir;
109bcmos_bool status_bcm_cli_quit = BCMOS_FALSE;
110bcmos_task bal_cli_thread;
111const char *bal_cli_thread_name = "bal_cli_thread";
112uint16_t flow_id_counters = 0;
113int flow_id_data[16384][2];
114
115/* QOS Type has been pre-defined as Fixed Queue but it will be updated based on number of GEMPORTS
116 associated for a given subscriber. If GEM count = 1 for a given subscriber, qos_type will be Fixed Queue
117 else Priority to Queue */
118bcmolt_egress_qos_type qos_type = BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700119
Shad Ansariedef2132018-08-10 22:14:50 +0000120State state;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400121
Craig Lutgen967a1d02018-11-27 10:41:51 -0600122static std::map<uint32_t, uint32_t> flowid_to_port; // For mapping upstream flows to logical ports
123static std::map<uint32_t, uint32_t> flowid_to_gemport; // For mapping downstream flows into gemports
124static 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 -0800125
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000126/* This represents the Key to 'sched_map' map.
127 Represents (pon_intf_id, onu_id, uni_id, direction) */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800128typedef std::tuple<uint32_t, uint32_t, uint32_t, std::string> sched_map_key_tuple;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000129/* 'sched_map' maps sched_map_key_tuple to DBA (Upstream) or
130 Subscriber (Downstream) Scheduler ID */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800131static std::map<sched_map_key_tuple, int> sched_map;
132
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000133/* This represents the Key to 'sched_qmp_id_map' map.
134Represents (sched_id, pon_intf_id, onu_id, uni_id) */
135typedef std::tuple<uint32_t, uint32_t, uint32_t, uint32_t> sched_qmp_id_map_key_tuple;
136/* 'sched_qmp_id_map' maps sched_qmp_id_map_key_tuple to TM Queue Mapping Profile ID */
137static std::map<sched_qmp_id_map_key_tuple, int> sched_qmp_id_map;
138/* 'qmp_id_to_qmp_map' maps TM Queue Mapping Profile ID to TM Queue Mapping Profile */
139static std::map<int, std::vector < uint32_t > > qmp_id_to_qmp_map;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800140
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800141std::bitset<MAX_TM_SCHED_ID> tm_sched_bitset;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000142std::bitset<MAX_TM_QMP_ID> tm_qmp_bitset;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800143
144static bcmos_fastlock data_lock;
Craig Lutgen967a1d02018-11-27 10:41:51 -0600145
146#define MIN_ALLOC_ID_GPON 256
147#define MIN_ALLOC_ID_XGSPON 1024
148
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800149static bcmos_errno CreateSched(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
150 uint32_t port_no, uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, \
151 uint32_t priority, tech_profile::SchedulingPolicy sched_policy,
152 tech_profile::TrafficShapingInfo traffic_shaping_info);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000153static 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 -0800154static bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
155 uint32_t priority, uint32_t gemport_id);
156static bcmos_errno RemoveQueue(std::string direction, int intf_id, int onu_id, int uni_id, uint32_t port_no, int alloc_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000157static bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction);
158static bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction);
159
160uint16_t get_dev_id(void) {
161 return dev_id;
162}
Shad Ansari627b5782018-08-13 22:49:32 +0000163
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800164/**
165* Returns the default NNI (Upstream direction) or PON (Downstream direction) scheduler
166* Every NNI port and PON port have default scheduler.
167* The NNI0 default scheduler ID is 18432, and NNI1 is 18433 and so on.
168* Similarly, PON0 default scheduler ID is 16384. PON1 is 16385 and so on.
169*
170* @param intf_id NNI or PON interface ID
171* @param direction "upstream" or "downstream"
172*
173* @return default scheduler ID for the given interface.
174*/
175static inline int get_default_tm_sched_id(int intf_id, std::string direction) {
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700176 if (direction.compare(upstream) == 0) {
177 return tm_upstream_sched_id_start + intf_id;
178 } else if (direction.compare(downstream) == 0) {
179 return tm_downstream_sched_id_start + intf_id;
180 }
181 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000182 OPENOLT_LOG(ERROR, openolt_log_id, "invalid direction - %s\n", direction.c_str());
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700183 return 0;
184 }
185}
186
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800187/**
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800188* Gets a unique tm_sched_id for a given intf_id, onu_id, uni_id, gemport_id, direction
189* The tm_sched_id is locally cached in a map, so that it can rendered when necessary.
190* VOLTHA replays whole configuration on OLT reboot, so caching locally is not a problem
191*
192* @param intf_id NNI or PON intf ID
193* @param onu_id ONU ID
194* @param uni_id UNI ID
195* @param gemport_id GEM Port ID
196* @param direction Upstream or downstream
197*
198* @return tm_sched_id
199*/
200uint32_t get_tm_sched_id(int pon_intf_id, int onu_id, int uni_id, std::string direction) {
201 sched_map_key_tuple key(pon_intf_id, onu_id, uni_id, direction);
202 int sched_id = -1;
203
204 std::map<sched_map_key_tuple, int>::const_iterator it = sched_map.find(key);
205 if (it != sched_map.end()) {
206 sched_id = it->second;
207 }
208 if (sched_id != -1) {
209 return sched_id;
210 }
211
212 bcmos_fastlock_lock(&data_lock);
213 // Complexity of O(n). Is there better way that can avoid linear search?
214 for (sched_id = 0; sched_id < MAX_TM_SCHED_ID; sched_id++) {
215 if (tm_sched_bitset[sched_id] == 0) {
216 tm_sched_bitset[sched_id] = 1;
217 break;
218 }
219 }
220 bcmos_fastlock_unlock(&data_lock, 0);
221
222 if (sched_id < MAX_TM_SCHED_ID) {
223 bcmos_fastlock_lock(&data_lock);
224 sched_map[key] = sched_id;
225 bcmos_fastlock_unlock(&data_lock, 0);
226 return sched_id;
227 } else {
228 return -1;
229 }
230}
231
232/**
233* Free tm_sched_id for a given intf_id, onu_id, uni_id, gemport_id, direction
234*
235* @param intf_id NNI or PON intf ID
236* @param onu_id ONU ID
237* @param uni_id UNI ID
238* @param gemport_id GEM Port ID
239* @param direction Upstream or downstream
240*/
241void free_tm_sched_id(int pon_intf_id, int onu_id, int uni_id, std::string direction) {
242 sched_map_key_tuple key(pon_intf_id, onu_id, uni_id, direction);
243 std::map<sched_map_key_tuple, int>::const_iterator it;
244 bcmos_fastlock_lock(&data_lock);
245 it = sched_map.find(key);
246 if (it != sched_map.end()) {
247 tm_sched_bitset[it->second] = 0;
248 sched_map.erase(it);
249 }
250 bcmos_fastlock_unlock(&data_lock, 0);
251}
252
253bool is_tm_sched_id_present(int pon_intf_id, int onu_id, int uni_id, std::string direction) {
254 sched_map_key_tuple key(pon_intf_id, onu_id, uni_id, direction);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000255 std::map<sched_map_key_tuple, int>::const_iterator it = sched_map.find(key);
256 if (it != sched_map.end()) {
257 return true;
258 }
259 return false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800260}
261
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000262/**
263* Check whether given two tm qmp profiles are equal or not
264*
265* @param tmq_map_profileA <vector> TM QUEUE MAPPING PROFILE
266* @param tmq_map_profileB <vector> TM QUEUE MAPPING PROFILE
267*
268* @return boolean, true if given tmq_map_profiles are equal else false
269*/
270
271bool check_tm_qmp_equality(std::vector<uint32_t> tmq_map_profileA, std::vector<uint32_t> tmq_map_profileB) {
272 for (uint32_t i = 0; i < TMQ_MAP_PROFILE_SIZE; i++) {
273 if (tmq_map_profileA[i] != tmq_map_profileB[i]) {
274 return false;
275 }
276 }
277 return true;
Shad Ansari627b5782018-08-13 22:49:32 +0000278}
279
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000280/**
281* Modifies given queues_pbit_map to parsable format
282* e.g: Modifes "0b00000101" to "10100000"
283*
284* @param queues_pbit_map PBIT MAP configured for each GEM in TECH PROFILE
285* @param size Queue count
286*
287* @return string queues_pbit_map
288*/
289std::string* get_valid_queues_pbit_map(std::string *queues_pbit_map, uint32_t size) {
290 for(uint32_t i=0; i < size; i++) {
291 /* Deletes 2 characters from index number 0 */
292 queues_pbit_map[i].erase(0, 2);
293 std::reverse(queues_pbit_map[i].begin(), queues_pbit_map[i].end());
294 }
295 return queues_pbit_map;
296}
297
298/**
299* Creates TM QUEUE MAPPING PROFILE for given queues_pbit_map and queues_priority_q
300*
301* @param queues_pbit_map PBIT MAP configured for each GEM in TECH PROFILE
302* @param queues_priority_q PRIORITY_Q configured for each GEM in TECH PROFILE
303* @param size Queue count
304*
305* @return <vector> TM QUEUE MAPPING PROFILE
306*/
307std::vector<uint32_t> get_tmq_map_profile(std::string *queues_pbit_map, uint32_t *queues_priority_q, uint32_t size) {
308 std::vector<uint32_t> tmq_map_profile(8,0);
309
310 for(uint32_t i=0; i < size; i++) {
311 for (uint32_t j = 0; j < queues_pbit_map[i].size(); j++) {
312 if (queues_pbit_map[i][j]=='1') {
313 tmq_map_profile.at(j) = queue_id_list[queues_priority_q[i]];
314 }
315 }
316 }
317 return tmq_map_profile;
318}
319
320/**
321* Gets corresponding tm_qmp_id for a given tmq_map_profile
322*
323* @param <vector> TM QUEUE MAPPING PROFILE
324*
325* @return tm_qmp_id
326*/
327int get_tm_qmp_id(std::vector<uint32_t> tmq_map_profile) {
328 int tm_qmp_id = -1;
329
330 std::map<int, std::vector < uint32_t > >::const_iterator it = qmp_id_to_qmp_map.begin();
331 while(it != qmp_id_to_qmp_map.end()) {
332 if(check_tm_qmp_equality(tmq_map_profile, it->second)) {
333 tm_qmp_id = it->first;
334 break;
335 }
336 it++;
337 }
338 return tm_qmp_id;
339}
340
341/**
342* Updates sched_qmp_id_map with given sched_id, pon_intf_id, onu_id, uni_id, tm_qmp_id
343*
344* @param upstream/downstream sched_id
345* @param PON intf ID
346* @param onu_id ONU ID
347* @param uni_id UNI ID
348* @param tm_qmp_id TM QUEUE MAPPING PROFILE ID
349*/
350void update_sched_qmp_id_map(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, \
351 uint32_t uni_id, int tm_qmp_id) {
352 bcmos_fastlock_lock(&data_lock);
353 sched_qmp_id_map_key_tuple key(sched_id, pon_intf_id, onu_id, uni_id);
354 sched_qmp_id_map.insert(make_pair(key, tm_qmp_id));
355 bcmos_fastlock_unlock(&data_lock, 0);
356}
357
358/**
359* Gets corresponding tm_qmp_id for a given sched_id, pon_intf_id, onu_id, uni_id
360*
361* @param upstream/downstream sched_id
362* @param PON intf ID
363* @param onu_id ONU ID
364* @param uni_id UNI ID
365*
366* @return tm_qmp_id
367*/
368int get_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id) {
369 sched_qmp_id_map_key_tuple key(sched_id, pon_intf_id, onu_id, uni_id);
370 int tm_qmp_id = -1;
371
372 std::map<sched_qmp_id_map_key_tuple, int>::const_iterator it = sched_qmp_id_map.find(key);
373 if (it != sched_qmp_id_map.end()) {
374 tm_qmp_id = it->second;
375 }
376 return tm_qmp_id;
377}
378
379/**
380* Gets a unique tm_qmp_id for a given tmq_map_profile
381* The tm_qmp_id is locally cached in a map, so that it can be rendered when necessary.
382* VOLTHA replays whole configuration on OLT reboot, so caching locally is not a problem
383*
384* @param upstream/downstream sched_id
385* @param PON intf ID
386* @param onu_id ONU ID
387* @param uni_id UNI ID
388* @param <vector> TM QUEUE MAPPING PROFILE
389*
390* @return tm_qmp_id
391*/
392int get_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id, \
393 std::vector<uint32_t> tmq_map_profile) {
394 int tm_qmp_id;
395
396 bcmos_fastlock_lock(&data_lock);
397 /* Complexity of O(n). Is there better way that can avoid linear search? */
398 for (tm_qmp_id = 0; tm_qmp_id < MAX_TM_QMP_ID; tm_qmp_id++) {
399 if (tm_qmp_bitset[tm_qmp_id] == 0) {
400 tm_qmp_bitset[tm_qmp_id] = 1;
401 break;
402 }
403 }
404 bcmos_fastlock_unlock(&data_lock, 0);
405
406 if (tm_qmp_id < MAX_TM_QMP_ID) {
407 bcmos_fastlock_lock(&data_lock);
408 qmp_id_to_qmp_map.insert(make_pair(tm_qmp_id, tmq_map_profile));
409 bcmos_fastlock_unlock(&data_lock, 0);
410 update_sched_qmp_id_map(sched_id, pon_intf_id, onu_id, uni_id, tm_qmp_id);
411 return tm_qmp_id;
412 } else {
413 return -1;
414 }
415}
416
417/**
418* Free tm_qmp_id for a given sched_id, pon_intf_id, onu_id, uni_id
419*
420* @param upstream/downstream sched_id
421* @param PON intf ID
422* @param onu_id ONU ID
423* @param uni_id UNI ID
424* @param tm_qmp_id TM QUEUE MAPPING PROFILE ID
425*
426* @return boolean, true if no more reference for TM QMP else false
427*/
428bool free_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, \
429 uint32_t uni_id, int tm_qmp_id) {
430 bool result;
431 sched_qmp_id_map_key_tuple key(sched_id, pon_intf_id, onu_id, uni_id);
432 std::map<sched_qmp_id_map_key_tuple, int>::const_iterator it = sched_qmp_id_map.find(key);
433 bcmos_fastlock_lock(&data_lock);
434 if (it != sched_qmp_id_map.end()) {
435 sched_qmp_id_map.erase(it);
436 }
437 bcmos_fastlock_unlock(&data_lock, 0);
438
439 uint32_t tm_qmp_ref_count = 0;
440 std::map<sched_qmp_id_map_key_tuple, int>::const_iterator it2 = sched_qmp_id_map.begin();
441 while(it2 != sched_qmp_id_map.end()) {
442 if(it2->second == tm_qmp_id) {
443 tm_qmp_ref_count++;
444 }
445 it2++;
446 }
447
448 if (tm_qmp_ref_count == 0) {
449 std::map<int, std::vector < uint32_t > >::const_iterator it3 = qmp_id_to_qmp_map.find(tm_qmp_id);
450 if (it3 != qmp_id_to_qmp_map.end()) {
451 bcmos_fastlock_lock(&data_lock);
452 tm_qmp_bitset[tm_qmp_id] = 0;
453 qmp_id_to_qmp_map.erase(it3);
454 bcmos_fastlock_unlock(&data_lock, 0);
455 OPENOLT_LOG(INFO, openolt_log_id, "Reference count for tm qmp profile id %d is : %d. So clearing it\n", \
456 tm_qmp_id, tm_qmp_ref_count);
457 result = true;
458 }
459 } else {
460 OPENOLT_LOG(INFO, openolt_log_id, "Reference count for tm qmp profile id %d is : %d. So not clearing it\n", \
461 tm_qmp_id, tm_qmp_ref_count);
462 result = false;
463 }
464 return result;
465}
466
467/**
468* Returns Scheduler/Queue direction as string
469*
470* @param direction as specified in tech_profile.proto
471*/
472std::string GetDirection(int direction) {
473 switch (direction)
474 {
475 case tech_profile::Direction::UPSTREAM: return upstream;
476 case tech_profile::Direction::DOWNSTREAM: return downstream;
477 default: OPENOLT_LOG(ERROR, openolt_log_id, "direction-not-supported %d\n", direction);
478 return "direction-not-supported";
479 }
480}
481
482inline const char *get_flow_acton_command(uint32_t command) {
483 char actions[200] = { };
484 char *s_actions_ptr = actions;
485 if (command & BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG) strcat(s_actions_ptr, "ADD_OUTER_TAG|");
486 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG) strcat(s_actions_ptr, "REMOVE_OUTER_TAG|");
487 if (command & BCMOLT_ACTION_CMD_ID_XLATE_OUTER_TAG) strcat(s_actions_ptr, "TRANSLATE_OUTER_TAG|");
488 if (command & BCMOLT_ACTION_CMD_ID_ADD_INNER_TAG) strcat(s_actions_ptr, "ADD_INNTER_TAG|");
489 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_INNER_TAG) strcat(s_actions_ptr, "REMOVE_INNER_TAG|");
490 if (command & BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG) strcat(s_actions_ptr, "TRANSLATE_INNER_TAG|");
491 if (command & BCMOLT_ACTION_CMD_ID_REMARK_OUTER_PBITS) strcat(s_actions_ptr, "REMOVE_OUTER_PBITS|");
492 if (command & BCMOLT_ACTION_CMD_ID_REMARK_INNER_PBITS) strcat(s_actions_ptr, "REMAKE_INNER_PBITS|");
493 return s_actions_ptr;
494}
495
496char* openolt_read_sysinfo(const char* field_name, char* field_val)
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800497{
498 FILE *fp;
499 /* Prepare the command*/
500 char command[150];
501
502 snprintf(command, sizeof command, "bash -l -c \"onlpdump -s\" | perl -ne 'print $1 if /%s: (\\S+)/'", field_name);
503 /* Open the command for reading. */
504 fp = popen(command, "r");
505 if (fp == NULL) {
506 /*The client has to check for a Null field value in this case*/
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000507 OPENOLT_LOG(INFO, openolt_log_id, "Failed to query the %s\n", field_name);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800508 return field_val;
509 }
510
511 /*Read the field value*/
512 if (fp) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000513 uint8_t ret;
514 ret = fread(field_val, OPENOLT_FIELD_LEN, 1, fp);
515 if (ret >= OPENOLT_FIELD_LEN)
516 OPENOLT_LOG(INFO, openolt_log_id, "Read data length %u\n", ret);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800517 pclose(fp);
518 }
519 return field_val;
520}
521
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400522Status GetDeviceInfo_(openolt::DeviceInfo* device_info) {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500523 device_info->set_vendor(VENDOR_ID);
524 device_info->set_model(MODEL_ID);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400525 device_info->set_hardware_version("");
526 device_info->set_firmware_version(firmware_version);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500527 device_info->set_technology(board_technology);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500528 device_info->set_pon_ports(num_of_pon_ports);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500529
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800530 char serial_number[OPENOLT_FIELD_LEN];
531 memset(serial_number, '\0', OPENOLT_FIELD_LEN);
532 openolt_read_sysinfo("Serial Number", serial_number);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000533 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device serial number %s\n", serial_number);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800534 device_info->set_device_serial_number(serial_number);
535
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700536 char device_id[OPENOLT_FIELD_LEN];
537 memset(device_id, '\0', OPENOLT_FIELD_LEN);
538 openolt_read_sysinfo("MAC", device_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000539 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device mac address %s\n", device_id);
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700540 device_info->set_device_id(device_id);
541
Craig Lutgenb2601f02018-10-23 13:04:31 -0500542 // Legacy, device-wide ranges. To be deprecated when adapter
543 // is upgraded to support per-interface ranges
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000544 if (board_technology == "XGS-PON") {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500545 device_info->set_onu_id_start(1);
546 device_info->set_onu_id_end(255);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600547 device_info->set_alloc_id_start(MIN_ALLOC_ID_XGSPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500548 device_info->set_alloc_id_end(16383);
549 device_info->set_gemport_id_start(1024);
550 device_info->set_gemport_id_end(65535);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500551 device_info->set_flow_id_start(1);
552 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500553 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000554 else if (board_technology == "GPON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500555 device_info->set_onu_id_start(1);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500556 device_info->set_onu_id_end(127);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600557 device_info->set_alloc_id_start(MIN_ALLOC_ID_GPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500558 device_info->set_alloc_id_end(767);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500559 device_info->set_gemport_id_start(256);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500560 device_info->set_gemport_id_end(4095);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500561 device_info->set_flow_id_start(1);
562 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500563 }
Craig Lutgenb2601f02018-10-23 13:04:31 -0500564
565 std::map<std::string, openolt::DeviceInfo::DeviceResourceRanges*> ranges;
566 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
567 std::string intf_technology = intf_technologies[intf_id];
568 openolt::DeviceInfo::DeviceResourceRanges *range = ranges[intf_technology];
569 if(range == nullptr) {
570 range = device_info->add_ranges();
571 ranges[intf_technology] = range;
572 range->set_technology(intf_technology);
573
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000574 if (intf_technology == "XGS-PON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500575 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
576
577 pool = range->add_pools();
578 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
579 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
580 pool->set_start(1);
581 pool->set_end(255);
582
583 pool = range->add_pools();
584 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
585 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_SAME_TECH);
586 pool->set_start(1024);
587 pool->set_end(16383);
588
589 pool = range->add_pools();
590 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
591 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
592 pool->set_start(1024);
593 pool->set_end(65535);
594
595 pool = range->add_pools();
596 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
597 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
598 pool->set_start(1);
599 pool->set_end(16383);
600 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000601 else if (intf_technology == "GPON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500602 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
603
604 pool = range->add_pools();
605 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
606 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
607 pool->set_start(1);
608 pool->set_end(127);
609
610 pool = range->add_pools();
611 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
612 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_SAME_TECH);
613 pool->set_start(256);
614 pool->set_end(757);
615
616 pool = range->add_pools();
617 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
618 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
619 pool->set_start(256);
620 pool->set_end(4095);
621
622 pool = range->add_pools();
623 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
624 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
625 pool->set_start(1);
626 pool->set_end(16383);
627 }
628 }
629
630 range->add_intf_ids(intf_id);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500631 }
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400632
633 // FIXME: Once dependency problem is fixed
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500634 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400635 // device_info->set_onu_id_end(XGPON_NUM_OF_ONUS - 1);
636 // device_info->set_alloc_id_start(1024);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500637 // device_info->set_alloc_id_end(XGPON_NUM_OF_ALLOC_IDS * num_of_pon_ports ? - 1);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400638 // device_info->set_gemport_id_start(XGPON_MIN_BASE_SERVICE_PORT_ID);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500639 // device_info->set_gemport_id_end(XGPON_NUM_OF_GEM_PORT_IDS_PER_PON * num_of_pon_ports ? - 1);
640 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400641
642 return Status::OK;
643}
644
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000645Status pushOltOperInd(uint32_t intf_id, const char *type, const char *state)
646{
647 openolt::Indication ind;
648 openolt::IntfOperIndication* intf_oper_ind = new openolt::IntfOperIndication;
649
650 intf_oper_ind->set_type(type);
651 intf_oper_ind->set_intf_id(intf_id);
652 intf_oper_ind->set_oper_state(state);
653 ind.set_allocated_intf_oper_ind(intf_oper_ind);
654 oltIndQ.push(ind);
655 return Status::OK;
656}
657
658#define CLI_HOST_PROMPT_FORMAT "BCM.%u> "
659
660/* Build CLI prompt */
661static void openolt_cli_get_prompt_cb(bcmcli_session *session, char *buf, uint32_t max_len)
662{
663 snprintf(buf, max_len, CLI_HOST_PROMPT_FORMAT, dev_id);
664}
665
666static int _bal_apiend_cli_thread_handler(long data)
667{
668 char init_string[]="\n";
669 bcmcli_session *sess = current_session;
670 bcmos_task_parm bal_cli_task_p_dummy;
671
672 /* Switch to interactive mode if not stopped in the init script */
673 if (!bcmcli_is_stopped(sess))
674 {
675 /* Force a CLI command prompt
676 * The string passed into the parse function
677 * must be modifiable, so a string constant like
678 * bcmcli_parse(current_session, "\n") will not
679 * work.
680 */
681 bcmcli_parse(sess, init_string);
682
683 /* Process user input until EOF or quit command */
684 bcmcli_driver(sess);
685 };
686 OPENOLT_LOG(INFO, openolt_log_id, "BAL API End CLI terminated\n");
687
688 /* Cleanup */
689 bcmcli_session_close(current_session);
690 bcmcli_token_destroy(NULL);
691 return 0;
692}
693
694/* Init API CLI commands for the current device */
695bcmos_errno bcm_openolt_api_cli_init(bcmcli_entry *parent_dir, bcmcli_session *session)
696{
697 bcmos_errno rc;
698
699 api_parent_dir = parent_dir;
700
701 rc = bcm_api_cli_set_commands(session);
702
703#ifdef BCM_SUBSYSTEM_HOST
704 /* Subscribe for device change indication */
705 rc = rc ? rc : bcmolt_olt_sel_ind_register(_api_cli_olt_change_ind);
706#endif
707
708 return rc;
709}
710
711static bcmos_errno bcm_cli_quit(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
712{
713 bcmcli_stop(session);
714 bcmcli_session_print(session, "CLI terminated by 'Quit' command\n");
715 status_bcm_cli_quit = BCMOS_TRUE;
716
717 return BCM_ERR_OK;
718}
719
720int get_status_bcm_cli_quit(void) {
721 return status_bcm_cli_quit;
722}
723
724bcmos_errno bcmolt_apiend_cli_init() {
725 bcmos_errno ret;
726 bcmos_task_parm bal_cli_task_p = {};
727 bcmos_task_parm bal_cli_task_p_dummy;
728
729 /** before creating the task, check if it is already created by the other half of BAL i.e. Core side */
730 if (BCM_ERR_OK != bcmos_task_query(&bal_cli_thread, &bal_cli_task_p_dummy))
731 {
732 /* Create BAL CLI thread */
733 bal_cli_task_p.name = bal_cli_thread_name;
734 bal_cli_task_p.handler = _bal_apiend_cli_thread_handler;
735 bal_cli_task_p.priority = TASK_PRIORITY_CLI;
736
737 ret = bcmos_task_create(&bal_cli_thread, &bal_cli_task_p);
738 if (BCM_ERR_OK != ret)
739 {
740 bcmos_printf("Couldn't create BAL API end CLI thread\n");
741 return ret;
742 }
743 }
744}
745
Shad Ansari627b5782018-08-13 22:49:32 +0000746Status Enable_(int argc, char *argv[]) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000747 bcmos_errno err;
748 bcmolt_host_init_parms init_parms = {};
749 init_parms.transport.type = BCM_HOST_API_CONN_LOCAL;
750 unsigned int failed_enable_device_cnt = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000751
Shad Ansariedef2132018-08-10 22:14:50 +0000752 if (!state.is_activated()) {
Shad Ansari627b5782018-08-13 22:49:32 +0000753
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500754 vendor_init();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000755 /* Initialize host subsystem */
756 err = bcmolt_host_init(&init_parms);
757 if (BCM_ERR_OK != err) {
758 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to init OLT\n");
759 return bcm_to_grpc_err(err, "Failed to init OLT");
760 }
761
762 bcmcli_session_parm mon_session_parm;
763 /* Create CLI session */
764 memset(&mon_session_parm, 0, sizeof(mon_session_parm));
765 mon_session_parm.get_prompt = openolt_cli_get_prompt_cb;
766 mon_session_parm.access_right = BCMCLI_ACCESS_ADMIN;
767 bcmos_errno rc = bcmcli_session_open(&mon_session_parm, &current_session);
768 BUG_ON(rc != BCM_ERR_OK);
769
770 /* API CLI */
771 bcm_openolt_api_cli_init(NULL, current_session);
772
773 /* Add quit command */
774 BCMCLI_MAKE_CMD_NOPARM(NULL, "quit", "Quit", bcm_cli_quit);
775
776 err = bcmolt_apiend_cli_init();
777 if (BCM_ERR_OK != err) {
778 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to add apiend init\n");
779 return bcm_to_grpc_err(err, "Failed to add apiend init");
780 }
781
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800782 bcmos_fastlock_init(&data_lock, 0);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000783 OPENOLT_LOG(INFO, openolt_log_id, "Enable OLT - %s-%s\n", VENDOR_ID, MODEL_ID);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600784
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000785 if (bcmolt_api_conn_mgr_is_connected(dev_id))
786 {
787 Status status = SubscribeIndication();
788 if (!status.ok()) {
789 OPENOLT_LOG(ERROR, openolt_log_id, "SubscribeIndication failed - %s : %s\n",
790 grpc_status_code_to_string(status.error_code()).c_str(),
791 status.error_message().c_str());
792 return status;
793 }
794 bcmos_errno err;
795 bcmolt_odid dev;
796 OPENOLT_LOG(INFO, openolt_log_id, "Enabling PON %d Devices ... \n", BCM_MAX_DEVS_PER_LINE_CARD);
797 for (dev = 0; dev < BCM_MAX_DEVS_PER_LINE_CARD; dev++) {
798 bcmolt_device_cfg dev_cfg = { };
799 bcmolt_device_key dev_key = { };
800 dev_key.device_id = dev;
801 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
802 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
803 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
804 if (err == BCM_ERR_NOT_CONNECTED) {
805 bcmolt_device_key key = {.device_id = dev};
806 bcmolt_device_connect oper;
807 BCMOLT_OPER_INIT(&oper, device, connect, key);
808 if (MODEL_ID == "asfvolt16") {
809 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
810 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_XGS__2_X);
811 } else if (MODEL_ID == "asgvolt64") {
812 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
813 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
814 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
815 }
816 err = bcmolt_oper_submit(dev_id, &oper.hdr);
817 if (err) {
818 failed_enable_device_cnt ++;
819 OPENOLT_LOG(ERROR, openolt_log_id, "Enable PON device %d failed, err %d\n", dev, err);
820 if (failed_enable_device_cnt == BCM_MAX_DEVS_PER_LINE_CARD) {
821 OPENOLT_LOG(ERROR, openolt_log_id, "failed to enable all the pon ports\n");
822 return Status(grpc::StatusCode::INTERNAL, "Failed to activate all PON ports");
823 }
824 }
825 bcmos_usleep(200000);
826 }
827 else {
828 OPENOLT_LOG(WARNING, openolt_log_id, "PON deivce %d already connected\n", dev);
829 state.activate();
830 }
831 }
832 init_stats();
Shad Ansari627b5782018-08-13 22:49:32 +0000833 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000834 }
Shad Ansariedef2132018-08-10 22:14:50 +0000835
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000836 /* Start CLI */
837 OPENOLT_LOG(INFO, def_log_id, "Starting CLI\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400838 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000839 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400840}
841
842Status Disable_() {
843 // bcmbal_access_terminal_cfg acc_term_obj;
844 // bcmbal_access_terminal_key key = { };
845 //
846 // if (state::is_activated) {
847 // std::cout << "Disable OLT" << std::endl;
848 // key.access_term_id = DEFAULT_ATERM_ID;
849 // BCMBAL_CFG_INIT(&acc_term_obj, access_terminal, key);
850 // BCMBAL_CFG_PROP_SET(&acc_term_obj, access_terminal, admin_state, BCMBAL_STATE_DOWN);
851 // bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(acc_term_obj.hdr));
852 // if (err) {
853 // std::cout << "ERROR: Failed to disable OLT" << std::endl;
854 // return bcm_to_grpc_err(err, "Failed to disable OLT");
855 // }
856 // }
857 // //If already disabled, generate an extra indication ????
858 // return Status::OK;
859 //This fails with Operation Not Supported, bug ???
860
861 //TEMPORARY WORK AROUND
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000862 Status status = SetStateUplinkIf_(nni_intf_id, false);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400863 if (status.ok()) {
Shad Ansariedef2132018-08-10 22:14:50 +0000864 state.deactivate();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000865 OPENOLT_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
866 pushOltOperInd(nni_intf_id, "nni", "up");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400867 }
868 return status;
869
870}
871
872Status Reenable_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000873 Status status = SetStateUplinkIf_(0, true);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400874 if (status.ok()) {
Shad Ansariedef2132018-08-10 22:14:50 +0000875 state.activate();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000876 OPENOLT_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
877 pushOltOperInd(0, "nni", "up");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400878 }
879 return status;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000880}
881
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000882bcmos_errno get_pon_interface_status(bcmolt_interface pon_ni, bcmolt_interface_state *state) {
883 bcmos_errno err;
884 bcmolt_pon_interface_key pon_key;
885 bcmolt_pon_interface_cfg pon_cfg;
886 pon_key.pon_ni = pon_ni;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000887
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000888 BCMOLT_CFG_INIT(&pon_cfg, pon_interface, pon_key);
889 BCMOLT_FIELD_SET_PRESENT(&pon_cfg.data, pon_interface_cfg_data, state);
890 BCMOLT_FIELD_SET_PRESENT(&pon_cfg.data, pon_interface_cfg_data, itu);
891 err = bcmolt_cfg_get(dev_id, &pon_cfg.hdr);
892 *state = pon_cfg.data.state;
893 return err;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000894}
895
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000896inline uint64_t get_flow_status(uint16_t flow_id, uint16_t flow_type, uint16_t data_id) {
897 bcmos_errno err;
898 bcmolt_flow_key flow_key;
899 bcmolt_flow_cfg flow_cfg;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400900
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000901 flow_key.flow_id = flow_id;
902 flow_key.flow_type = (bcmolt_flow_type)flow_type;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400903
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000904 BCMOLT_CFG_INIT(&flow_cfg, flow, flow_key);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400905
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000906 switch (data_id) {
907 case ONU_ID: //onu_id
908 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, onu_id);
909 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
910 if (err) {
911 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get onu_id\n");
912 return err;
913 }
914 return flow_cfg.data.onu_id;
915 case FLOW_TYPE:
916 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
917 if (err) {
918 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get flow_type\n");
919 return err;
920 }
921 return flow_cfg.key.flow_type;
922 case SVC_PORT_ID: //svc_port_id
923 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, svc_port_id);
924 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
925 if (err) {
926 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get svc_port_id\n");
927 return err;
928 }
929 return flow_cfg.data.svc_port_id;
930 case PRIORITY:
931 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, priority);
932 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
933 if (err) {
934 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get priority\n");
935 return err;
936 }
937 return flow_cfg.data.priority;
938 case COOKIE: //cookie
939 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, cookie);
940 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
941 if (err) {
942 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get cookie\n");
943 return err;
944 }
945 return flow_cfg.data.cookie;
946 case INGRESS_INTF_TYPE: //ingress intf_type
947 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
948 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
949 if (err) {
950 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get ingress intf_type\n");
951 return err;
952 }
953 return flow_cfg.data.ingress_intf.intf_type;
954 case EGRESS_INTF_TYPE: //egress intf_type
955 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
956 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
957 if (err) {
958 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress intf_type\n");
959 return err;
960 }
961 return flow_cfg.data.egress_intf.intf_type;
962 case INGRESS_INTF_ID: //ingress intf_id
963 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
964 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
965 if (err) {
966 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get ingress intf_id\n");
967 return err;
968 }
969 return flow_cfg.data.ingress_intf.intf_id;
970 case EGRESS_INTF_ID: //egress intf_id
971 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
972 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
973 if (err) {
974 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress intf_id\n");
975 return err;
976 }
977 return flow_cfg.data.egress_intf.intf_id;
978 case CLASSIFIER_O_VID:
979 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
980 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
981 if (err) {
982 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier o_vid\n");
983 return err;
984 }
985 return flow_cfg.data.classifier.o_vid;
986 case CLASSIFIER_O_PBITS:
987 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
988 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
989 if (err) {
990 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier o_pbits\n");
991 return err;
992 }
993 return flow_cfg.data.classifier.o_pbits;
994 case CLASSIFIER_I_VID:
995 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
996 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
997 if (err) {
998 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier i_vid\n");
999 return err;
1000 }
1001 return flow_cfg.data.classifier.i_vid;
1002 case CLASSIFIER_I_PBITS:
1003 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1004 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1005 if (err) {
1006 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier i_pbits\n");
1007 return err;
1008 }
1009 return flow_cfg.data.classifier.i_pbits;
1010 case CLASSIFIER_ETHER_TYPE:
1011 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1012 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1013 if (err) {
1014 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier ether_type\n");
1015 return err;
1016 }
1017 return flow_cfg.data.classifier.ether_type;
1018 case CLASSIFIER_IP_PROTO:
1019 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1020 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1021 if (err) {
1022 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier ip_proto\n");
1023 return err;
1024 }
1025 return flow_cfg.data.classifier.ip_proto;
1026 case CLASSIFIER_SRC_PORT:
1027 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1028 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1029 if (err) {
1030 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier src_port\n");
1031 return err;
1032 }
1033 return flow_cfg.data.classifier.src_port;
1034 case CLASSIFIER_DST_PORT:
1035 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1036 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1037 if (err) {
1038 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier dst_port\n");
1039 return err;
1040 }
1041 return flow_cfg.data.classifier.dst_port;
1042 case CLASSIFIER_PKT_TAG_TYPE:
1043 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1044 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1045 if (err) {
1046 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier pkt_tag_type\n");
1047 return err;
1048 }
1049 return flow_cfg.data.classifier.pkt_tag_type;
1050 case EGRESS_QOS_TYPE:
1051 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
1052 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1053 if (err) {
1054 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos type\n");
1055 return err;
1056 }
1057 return flow_cfg.data.egress_qos.type;
1058 case EGRESS_QOS_QUEUE_ID:
1059 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
1060 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1061 if (err) {
1062 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos queue_id\n");
1063 return err;
1064 }
1065 switch (flow_cfg.data.egress_qos.type) {
1066 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE:
1067 return flow_cfg.data.egress_qos.u.fixed_queue.queue_id;
1068 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE:
1069 return flow_cfg.data.egress_qos.u.tc_to_queue.tc_to_queue_id;
1070 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC:
1071 return flow_cfg.data.egress_qos.u.pbit_to_tc.tc_to_queue_id;
1072 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE:
1073 return flow_cfg.data.egress_qos.u.priority_to_queue.tm_q_set_id;
1074 case BCMOLT_EGRESS_QOS_TYPE_NONE:
1075 default:
1076 return -1;
1077 }
1078 case EGRESS_QOS_TM_SCHED_ID:
1079 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
1080 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1081 if (err) {
1082 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos tm_sched_id\n");
1083 return err;
1084 }
1085 return flow_cfg.data.egress_qos.tm_sched.id;
1086 case ACTION_CMDS_BITMASK:
1087 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1088 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1089 if (err) {
1090 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action cmds_bitmask\n");
1091 return err;
1092 }
1093 return flow_cfg.data.action.cmds_bitmask;
1094 case ACTION_O_VID:
1095 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1096 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1097 if (err) {
1098 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action o_vid\n");
1099 return err;
1100 }
1101 return flow_cfg.data.action.o_vid;
1102 case ACTION_O_PBITS:
1103 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1104 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1105 if (err) {
1106 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action o_pbits\n");
1107 return err;
1108 }
1109 return flow_cfg.data.action.o_pbits;
1110 case ACTION_I_VID:
1111 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1112 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1113 if (err) {
1114 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action i_vid\n");
1115 return err;
1116 }
1117 return flow_cfg.data.action.i_vid;
1118 case ACTION_I_PBITS:
1119 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1120 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1121 if (err) {
1122 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action i_pbits\n");
1123 return err;
1124 }
1125 return flow_cfg.data.action.i_pbits;
1126 case STATE:
1127 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, state);
1128 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1129 if (err) {
1130 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get state\n");
1131 return err;
1132 }
1133 return flow_cfg.data.state;
1134 default:
1135 return BCM_ERR_INTERNAL;
1136 }
1137
1138 return err;
1139}
1140
1141Status EnablePonIf_(uint32_t intf_id) {
1142 bcmos_errno err = BCM_ERR_OK;
1143 bcmolt_pon_interface_cfg interface_obj;
1144 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1145 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
1146 bcmolt_interface_state state;
1147
1148 err = get_pon_interface_status((bcmolt_interface)intf_id, &state);
1149 if (err == BCM_ERR_OK) {
1150 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
1151 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
1152 return Status::OK;
1153 }
1154 }
1155 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
1156 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1157 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
1158 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.interval, 5000);
1159 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.onu_post_discovery_mode,
1160 BCMOLT_ONU_POST_DISCOVERY_MODE_ACTIVATE);
1161 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.los, true);
1162 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.onu_alarms, true);
1163 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.tiwi, true);
1164 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.ack_timeout, true);
1165 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.sfi, true);
1166 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.loki, true);
1167 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1168 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1169
1170 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1171 if (err != BCM_ERR_OK) {
1172 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to enable discovery onu, PON interface %d, err %d\n", intf_id, err);
1173 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
1174 }
1175 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1176 if (err != BCM_ERR_OK) {
1177 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", intf_id);
1178 return bcm_to_grpc_err(err, "Failed to enable PON interface");
1179 }
1180 else {
1181 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
1182 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
1183 CreateDefaultSched(intf_id, downstream);
1184 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001185 }
1186
1187 return Status::OK;
1188}
1189
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001190Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001191 bcmos_errno err;
1192 bcmolt_device_cfg dev_cfg = { };
1193 bcmolt_device_key dev_key = { };
1194 bcmolt_olt_cfg olt_cfg = { };
1195 bcmolt_olt_key olt_key = { };
1196 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
1197 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001198
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001199 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
1200 topo.topology_maps.arr = &topo_map[0];
1201 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
1202 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
1203 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
1204 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
1205 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
1206 err = bcmolt_cfg_get(dev_id, &olt_cfg.hdr);
1207 if (err) {
1208 OPENOLT_LOG(ERROR, openolt_log_id, "cfg: Failed to query OLT\n");
1209 return bcm_to_grpc_err(err, "cfg: Failed to query OLT");
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001210 }
1211
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001212 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
1213 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001214
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001215 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
1216 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
1217 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001218
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001219 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
1220 num_of_nni_ports,
1221 num_of_pon_ports,
1222 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001223
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001224 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
1225 dev_key.device_id = devid;
1226 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
1227 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
1228 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
1229 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
1230 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
1231 if (err) {
1232 OPENOLT_LOG(ERROR, openolt_log_id, "device: Failed to query OLT\n");
1233 return bcm_to_grpc_err(err, "device: Failed to query OLT");
1234 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001235
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001236 std::string bal_version;
1237 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
1238 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
1239 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
1240 firmware_version = "BAL." + bal_version + "__" + firmware_version;
1241
1242 switch(dev_cfg.data.system_mode) {
1243 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
1244 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
1245 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
1246 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
1247 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
1248 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
1249 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
1250 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
1251 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
1252 case 20: board_technology = MIXED_TECH; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,MIXED_TECH); break;
1253 }
1254
1255 switch(dev_cfg.data.chip_family) {
1256 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X_: chip_family = "Maple"; break;
1257 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X_: chip_family = "Aspen"; break;
1258 }
1259
1260 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s object model: %d, family: %s, board_technology: %s\n",
1261 devid, BCM_MAX_PONS_PER_DEV, bal_version.c_str(), BAL_API_VERSION, chip_family.c_str(), board_technology.c_str());
1262
1263 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001264 }
1265
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001266 return Status::OK;
1267}
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001268#if 0
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001269Status ProbePonIfTechnology_() {
1270 // Probe maximum extent possible as configured into BAL driver to determine
1271 // which are active in the current BAL topology. And for those
1272 // that are active, determine each port's access technology, i.e. "gpon" or "xgspon".
1273 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001274 bcmolt_pon_interface_cfg interface_obj;
1275 bcmolt_pon_interface_key interface_key;
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001276
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001277 interface_key.pon_ni = intf_id;
1278 BCMOLT_CFG_INIT(&interface_obj, pon_interface, interface_key);
1279 if (board_technology == "XGS-PON")
1280 BCMOLT_MSG_FIELD_GET(&interface_obj, xgs_ngpon2_trx);
1281 else if (board_technology == "GPON")
1282 BCMOLT_MSG_FIELD_GET(&interface_obj, gpon_trx);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001283
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001284 bcmos_errno err = bcmolt_cfg_get(dev_id, &interface_obj.hdr);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001285 if (err != BCM_ERR_OK) {
Craig Lutgenb2601f02018-10-23 13:04:31 -05001286 intf_technologies[intf_id] = UNKNOWN_TECH;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001287 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 -05001288 }
1289 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001290 if (board_technology == "XGS-PON") {
1291 switch(interface_obj.data.xgpon_trx.transceiver_type) {
1292 case BCMOLT_XGPON_TRX_TYPE_LTH_7222_PC:
1293 case BCMOLT_XGPON_TRX_TYPE_WTD_RTXM266_702:
1294 case BCMOLT_XGPON_TRX_TYPE_LTH_7222_BC_PLUS:
1295 case BCMOLT_XGPON_TRX_TYPE_LTH_7226_PC:
1296 case BCMOLT_XGPON_TRX_TYPE_LTH_5302_PC:
1297 case BCMOLT_XGPON_TRX_TYPE_LTH_7226_A_PC_PLUS:
1298 case BCMOLT_XGPON_TRX_TYPE_D272RR_SSCB_DM:
1299 intf_technologies[intf_id] = "XGS-PON";
1300 break;
1301 }
1302 } else if (board_technology == "GPON") {
1303 switch(interface_obj.data.gpon_trx.transceiver_type) {
1304 case BCMOLT_TRX_TYPE_SPS_43_48_H_HP_CDE_SD_2013:
1305 case BCMOLT_TRX_TYPE_LTE_3680_M:
1306 case BCMOLT_TRX_TYPE_SOURCE_PHOTONICS:
1307 case BCMOLT_TRX_TYPE_LTE_3680_P_TYPE_C_PLUS:
1308 case BCMOLT_TRX_TYPE_LTE_3680_P_BC:
1309 intf_technologies[intf_id] = "GPON";
1310 break;
1311 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001312 }
Craig Lutgenb2601f02018-10-23 13:04:31 -05001313
1314 if (board_technology != UNKNOWN_TECH) {
1315 board_technology = intf_technologies[intf_id];
1316 } else if (board_technology != MIXED_TECH && board_technology != intf_technologies[intf_id]) {
1317 intf_technologies[intf_id] = MIXED_TECH;
1318 }
1319
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001320 }
1321 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001322 return Status::OK;
1323}
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001324#endif
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001325unsigned NumNniIf_() {return num_of_nni_ports;}
1326unsigned NumPonIf_() {return num_of_pon_ports;}
1327
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001328bcmos_errno get_nni_interface_status(bcmolt_interface id, bcmolt_interface_state *state) {
1329 bcmos_errno err;
1330 bcmolt_nni_interface_key nni_key;
1331 bcmolt_nni_interface_cfg nni_cfg;
1332 nni_key.id = id;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001333
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001334 BCMOLT_CFG_INIT(&nni_cfg, nni_interface, nni_key);
1335 BCMOLT_FIELD_SET_PRESENT(&nni_cfg.data, nni_interface_cfg_data, state);
1336 err = bcmolt_cfg_get(dev_id, &nni_cfg.hdr);
1337 *state = nni_cfg.data.state;
1338 return err;
1339}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001340
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001341Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
1342 bcmos_errno err = BCM_ERR_OK;
1343 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
1344 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
1345 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001346
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001347 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
1348 if (err == BCM_ERR_OK) {
1349 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
1350 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
1351 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1352 CreateDefaultSched(intf_id, upstream);
1353 CreateDefaultQueue(intf_id, upstream);
1354 return Status::OK;
1355 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1356 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
1357 return Status::OK;
1358 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001359 }
1360
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001361 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
1362 if (set_state) {
1363 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1364 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1365 } else {
1366 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1367 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1368 }
1369 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
1370 if (err != BCM_ERR_OK) {
1371 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err %d\n",
1372 (set_state)?"enable":"disable", intf_id, err);
1373 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
1374 }
1375 else {
1376 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
1377 if (set_state) {
1378 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1379 CreateDefaultSched(intf_id, upstream);
1380 CreateDefaultQueue(intf_id, upstream);
1381 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001382 }
1383
1384 return Status::OK;
1385}
1386
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001387Status DisablePonIf_(uint32_t intf_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001388 bcmolt_pon_interface_cfg interface_obj;
1389 bcmolt_pon_interface_key interface_key;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001390
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001391 interface_key.pon_ni = intf_id;
1392 BCMOLT_CFG_INIT(&interface_obj, pon_interface, interface_key);
1393 BCMOLT_MSG_FIELD_GET(&interface_obj, state);
1394 bcmos_errno err = bcmolt_cfg_get(dev_id, &interface_obj.hdr);
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001395 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001396 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", intf_id);
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001397 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001398 }
1399
1400 return Status::OK;
1401}
1402
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001403Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001404 const char *vendor_id, const char *vendor_specific, uint32_t pir) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001405 bcmos_errno err = BCM_ERR_OK;
1406 bcmolt_onu_cfg onu_cfg;
1407 bcmolt_onu_key onu_key;
1408 bcmolt_serial_number serial_number; /**< ONU serial number */
1409 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001410
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001411 onu_key.onu_id = onu_id;
1412 onu_key.pon_ni = intf_id;
1413 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1414 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1415 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
1416 if (err == BCM_ERR_OK) {
1417 if ((onu_cfg.data.onu_state == BCMOLT_ONU_STATE_PROCESSING ||
1418 onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) ||
1419 (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_INACTIVE &&
1420 onu_cfg.data.onu_old_state == BCMOLT_ONU_STATE_NOT_CONFIGURED))
1421 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001422 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001423
1424 OPENOLT_LOG(INFO, openolt_log_id, "Enabling ONU %d on PON %d : vendor id %s, \
1425vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
1426 vendor_specific_to_str(vendor_specific).c_str(), pir);
1427
1428 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1429 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1430 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1431 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1432 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1433 /*set burst and data profiles to fec disabled*/
1434 if (board_technology == "XGS-PON") {
1435 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1436 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1437 } else if (board_technology == "GPON") {
1438 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1439 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1440 }
1441 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1442 if (err != BCM_ERR_OK) {
1443 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to set activate ONU %d on PON %d, err %d\n", onu_id, intf_id, err);
1444 return bcm_to_grpc_err(err, "Failed to activate ONU");
1445 }
1446
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001447 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001448}
1449
Jonathan Davis70c21812018-07-19 15:32:10 -04001450Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1451 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001452 bcmos_errno err = BCM_ERR_OK;
1453 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1454 bcmolt_onu_cfg onu_cfg;
1455 bcmolt_onu_key onu_key; /**< Object key. */
1456 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001457
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001458 onu_key.onu_id = onu_id;
1459 onu_key.pon_ni = intf_id;
1460 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1461 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1462 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
1463 if (err == BCM_ERR_OK) {
1464 switch (onu_state) {
1465 case BCMOLT_ONU_OPERATION_ACTIVE:
1466 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
1467 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
1468 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1469 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1470 if (err != BCM_ERR_OK) {
1471 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to \
1472deactivate ONU %d on PON %d, err %d\n", onu_id, intf_id, err);
1473 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1474 }
1475 break;
1476 }
Jonathan Davis70c21812018-07-19 15:32:10 -04001477 }
1478
1479 return Status::OK;
1480}
1481
1482Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001483 const char *vendor_id, const char *vendor_specific) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001484
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001485 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 -05001486 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1487
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001488 // Need to deactivate before removing it (BAL rules)
1489
1490 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
1491 // Sleep to allow the state to propagate
1492 // We need the subscriber terminal object to be admin down before removal
1493 // Without sleep the race condition is lost by ~ 20 ms
1494 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1495
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001496 // TODO: Delete the schedulers and queues.
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001497
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001498 bcmolt_onu_cfg cfg_obj;
1499 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001500
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001501 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 -04001502 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001503
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001504 key.onu_id = onu_id;
1505 key.pon_ni = intf_id;
1506 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001507
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001508 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001509 if (err != BCM_ERR_OK)
1510 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001511 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to clear information for BAL subscriber_terminal_id %d, Interface ID %d\n",
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001512 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001513 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1514 }
1515
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001516 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001517}
1518
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001519#define MAX_CHAR_LENGTH 20
1520#define MAX_OMCI_MSG_LENGTH 44
1521Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001522 bcmolt_bin_str buf = {};
1523 bcmolt_onu_cpu_packets omci_cpu_packets;
1524 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001525
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001526 key.pon_ni = intf_id;
1527 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001528
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001529 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1530 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1531 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001532
1533 // ???
1534 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1535 buf.len = MAX_OMCI_MSG_LENGTH;
1536 } else {
1537 buf.len = pkt.size()/2;
1538 }
1539
1540 /* Send the OMCI packet using the BAL remote proxy API */
1541 uint16_t idx1 = 0;
1542 uint16_t idx2 = 0;
1543 uint8_t arraySend[buf.len];
1544 char str1[MAX_CHAR_LENGTH];
1545 char str2[MAX_CHAR_LENGTH];
1546 memset(&arraySend, 0, buf.len);
1547
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001548 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1549 sprintf(str1,"%c", pkt[idx1]);
1550 sprintf(str2,"%c", pkt[++idx1]);
1551 strcat(str1,str2);
1552 arraySend[idx2] = strtol(str1, NULL, 16);
1553 }
1554
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001555 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1556 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001557
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001558 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1559 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1560 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001561
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001562 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001563 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001564 OPENOLT_LOG(ERROR, omci_log_id, "Error sending OMCI message to ONU %d on PON %d\n", onu_id, intf_id);
1565 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001566 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001567 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 -05001568 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001569 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001570 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001571
1572 return Status::OK;
1573}
1574
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001575Status 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 +00001576 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1577 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1578 bcmolt_bin_str buf = {};
1579 bcmolt_gem_port_id gem_port_id_array[1];
1580 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001581
Craig Lutgen967a1d02018-11-27 10:41:51 -06001582 if (port_no > 0) {
1583 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001584 if (gemport_id == 0) {
1585 bcmos_fastlock_lock(&data_lock);
1586 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1587 // Pick any flow that is mapped with the same port_no.
1588 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1589 if (it != port_to_flows.end() && !it->second.empty()) {
1590 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1591 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1592 if (fit != flowid_to_gemport.end()) {
1593 found = true;
1594 gemport_id = fit->second;
1595 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001596 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001597 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001598
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001599 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001600 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 -08001601 onu_id, port_no, intf_id);
1602 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1603 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001604 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 -08001605 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001606 }
1607
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001608 gem_port_id_array[0] = gemport_id;
1609 gem_port_list.len = 1;
1610 gem_port_list.arr = gem_port_id_array;
1611 buf.len = pkt.size();
1612 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1613 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1614
1615 /* init the API struct */
1616 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1617 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1618 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1619 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1620 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1621
1622 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1623 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1624
1625 /* call API */
1626 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001627 }
1628 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001629 //TODO: Port No is 0, it is coming sender requirement.
1630 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1631 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001632 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001633 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001634
1635 return Status::OK;
1636}
1637
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001638Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001639 bcmolt_flow_key key = {}; /* declare key */
1640 bcmolt_bin_str buffer = {};
1641 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001642
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001643 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
1644 bcmolt_flow_id flow_id = 0;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001645
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001646 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1647 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1648 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1649 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1650 key.flow_id = flow_id;
1651 else {
1652 if (flow_id_counters != 0) {
1653 for (int flowid=0; flowid < flow_id_counters; flowid++) {
1654 int flow_index = flow_id_data[flowid][0];
1655 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1656 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1657 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1658 key.flow_id = flow_index;
1659 break;
1660 }
1661 }
1662 }
1663 else {
1664 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1665 }
1666 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001667
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001668 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001669
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001670 /* Initialize the API struct. */
1671 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001672
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001673 buffer.len = pkt.size();
1674 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1675 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1676 if (buffer.arr == NULL) {
1677 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1678 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1679 }
1680 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1681
1682 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1683 if (err) {
1684 OPENOLT_LOG(ERROR, openolt_log_id, "Error sending packets via nni port %d, flow_id %d err %d\n", intf_id, key.flow_id, err);
1685 } else {
1686 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1687 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001688
1689 return Status::OK;
1690}
1691
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001692uint32_t GetPortNum_(uint32_t flow_id) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001693 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001694 uint32_t port_no = 0;
1695 std::map<uint32_t, uint32_t >::const_iterator it = flowid_to_port.find(flow_id);
1696 if (it != flowid_to_port.end()) {
1697 port_no = it->second;
1698 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001699 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001700 return port_no;
1701}
1702
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001703#define FLOW_LOG(level,msg,err) \
1704 do { \
1705 OPENOLT_LOG(level, openolt_log_id, "--------> %s (flow_id %d) err: %d <--------\n", msg, key.flow_id, err); \
1706 OPENOLT_LOG(level, openolt_log_id, "intf_id %d, onu_id %d, uni_id %d, port_no %u, cookie %"PRIu64"\n", \
1707 access_intf_id, onu_id, uni_id, port_no, cookie); \
1708 OPENOLT_LOG(level, openolt_log_id, "flow_type %s, queue_id %d, sched_id %d\n", flow_type.c_str(), \
1709 cfg.data.egress_qos.u.fixed_queue.queue_id, cfg.data.egress_qos.tm_sched.id); \
1710 OPENOLT_LOG(level, openolt_log_id, "Ingress(intfd_type %s, intf_id %d), Egress(intf_type %s, intf_id %d)\n", \
1711 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type), cfg.data.ingress_intf.intf_id, \
1712 GET_FLOW_INTERFACE_TYPE(cfg.data.egress_intf.intf_type), cfg.data.egress_intf.intf_id); \
1713 OPENOLT_LOG(level, openolt_log_id, "classifier(o_vid %d, o_pbits %d, i_vid %d, i_pbits %d, ether type 0x%x)\n", \
1714 c_val.o_vid, c_val.o_pbits, c_val.i_vid, c_val.i_pbits, classifier.eth_type()); \
1715 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", \
1716 c_val.ip_proto, gemport_id, c_val.src_port, c_val.dst_port, GET_PKT_TAG_TYPE(c_val.pkt_tag_type)); \
1717 OPENOLT_LOG(level, openolt_log_id, "action(cmds_bitmask %s, o_vid %d, o_pbits %d, i_vid %d, i_pbits %d)\n\n", \
1718 get_flow_acton_command(a_val.cmds_bitmask), a_val.o_vid, a_val.o_pbits, a_val.i_vid, a_val.i_pbits); \
1719 } while(0)
1720
1721#define FLOW_PARAM_LOG() \
1722 do { \
1723 OPENOLT_LOG(INFO, openolt_log_id, "--------> flow comparison (now before) <--------\n"); \
1724 OPENOLT_LOG(INFO, openolt_log_id, "flow_id (%d %d)\n", \
1725 key.flow_id, flow_index); \
1726 OPENOLT_LOG(INFO, openolt_log_id, "onu_id (%d %lu)\n", \
1727 cfg.data.onu_id , get_flow_status(flow_index, flow_id_data[flowid][1], ONU_ID)); \
1728 OPENOLT_LOG(INFO, openolt_log_id, "type (%d %lu)\n", \
1729 key.flow_type, get_flow_status(flow_index, flow_id_data[flowid][1], FLOW_TYPE)); \
1730 OPENOLT_LOG(INFO, openolt_log_id, "svc_port_id (%d %lu)\n", \
1731 cfg.data.svc_port_id, get_flow_status(flow_index, flow_id_data[flowid][1], SVC_PORT_ID)); \
1732 OPENOLT_LOG(INFO, openolt_log_id, "priority (%d %lu)\n", \
1733 cfg.data.priority, get_flow_status(flow_index, flow_id_data[flowid][1], PRIORITY)); \
1734 OPENOLT_LOG(INFO, openolt_log_id, "cookie (%lu %lu)\n", \
1735 cfg.data.cookie, get_flow_status(flow_index, flow_id_data[flowid][1], COOKIE)); \
1736 OPENOLT_LOG(INFO, openolt_log_id, "ingress intf_type (%s %s)\n", \
1737 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type), \
1738 GET_FLOW_INTERFACE_TYPE(get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_TYPE))); \
1739 OPENOLT_LOG(INFO, openolt_log_id, "ingress intf id (%d %lu)\n", \
1740 cfg.data.ingress_intf.intf_id , get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_ID)); \
1741 OPENOLT_LOG(INFO, openolt_log_id, "egress intf_type (%d %lu)\n", \
1742 cfg.data.egress_intf.intf_type , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_TYPE)); \
1743 OPENOLT_LOG(INFO, openolt_log_id, "egress intf_id (%d %lu)\n", \
1744 cfg.data.egress_intf.intf_id , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_ID)); \
1745 OPENOLT_LOG(INFO, openolt_log_id, "classifier o_vid (%d %lu)\n", \
1746 c_val.o_vid , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_VID)); \
1747 OPENOLT_LOG(INFO, openolt_log_id, "classifier o_pbits (%d %lu)\n", \
1748 c_val.o_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_PBITS)); \
1749 OPENOLT_LOG(INFO, openolt_log_id, "classifier i_vid (%d %lu)\n", \
1750 c_val.i_vid , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_VID)); \
1751 OPENOLT_LOG(INFO, openolt_log_id, "classifier i_pbits (%d %lu)\n", \
1752 c_val.i_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_PBITS)); \
1753 OPENOLT_LOG(INFO, openolt_log_id, "classifier ether_type (0x%x 0x%lx)\n", \
1754 c_val.ether_type , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_ETHER_TYPE)); \
1755 OPENOLT_LOG(INFO, openolt_log_id, "classifier ip_proto (%d %lu)\n", \
1756 c_val.ip_proto , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_IP_PROTO)); \
1757 OPENOLT_LOG(INFO, openolt_log_id, "classifier src_port (%d %lu)\n", \
1758 c_val.src_port , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_SRC_PORT)); \
1759 OPENOLT_LOG(INFO, openolt_log_id, "classifier dst_port (%d %lu)\n", \
1760 c_val.dst_port , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_DST_PORT)); \
1761 OPENOLT_LOG(INFO, openolt_log_id, "classifier pkt_tag_type (%s %s)\n", \
1762 GET_PKT_TAG_TYPE(c_val.pkt_tag_type), \
1763 GET_PKT_TAG_TYPE(get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_PKT_TAG_TYPE))); \
1764 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos type (%d %lu)\n", \
1765 cfg.data.egress_qos.type , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TYPE)); \
1766 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos queue_id (%d %lu)\n", \
1767 cfg.data.egress_qos.u.fixed_queue.queue_id, \
1768 get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_QUEUE_ID)); \
1769 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos sched_id (%d %lu)\n", \
1770 cfg.data.egress_qos.tm_sched.id, \
1771 get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TM_SCHED_ID)); \
1772 OPENOLT_LOG(INFO, openolt_log_id, "classifier cmds_bitmask (%s %s)\n", \
1773 get_flow_acton_command(a_val.cmds_bitmask), \
1774 get_flow_acton_command(get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_CMDS_BITMASK))); \
1775 OPENOLT_LOG(INFO, openolt_log_id, "action o_vid (%d %lu)\n", \
1776 a_val.o_vid , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_VID)); \
1777 OPENOLT_LOG(INFO, openolt_log_id, "action i_vid (%d %lu)\n", \
1778 a_val.i_vid , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_VID)); \
1779 OPENOLT_LOG(INFO, openolt_log_id, "action o_pbits (%d %lu)\n", \
1780 a_val.o_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_PBITS)); \
1781 OPENOLT_LOG(INFO, openolt_log_id, "action i_pbits (%d %lu)\n\n", \
1782 a_val.i_pbits, get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_PBITS)); \
1783 } while(0)
1784
1785#define FLOW_CHECKER
1786//#define SHOW_FLOW_PARAM
1787
Craig Lutgen967a1d02018-11-27 10:41:51 -06001788Status 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 +00001789 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001790 int32_t alloc_id, int32_t network_intf_id,
1791 int32_t gemport_id, const ::openolt::Classifier& classifier,
Craig Lutgen967a1d02018-11-27 10:41:51 -06001792 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001793 bcmolt_flow_cfg cfg;
1794 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001795 int32_t o_vid = -1;
1796 bool single_tag = false;
1797 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001798 bcmolt_classifier c_val = { };
1799 bcmolt_action a_val = { };
1800 bcmolt_tm_queue_ref tm_val = { };
1801 int tm_qmp_id, tm_q_set_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001802
1803 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001804 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001805 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001806 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001807 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001808 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001809 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001810 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001811 }
1812
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001813 BCMOLT_CFG_INIT(&cfg, flow, key);
1814 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001815
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001816 if (access_intf_id >= 0 && network_intf_id >= 0) {
1817 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1818 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1819 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
1820 if (classifier.eth_type() == EAP_ETHER_TYPE || //EAPOL packet
1821 (classifier.ip_proto() == 17 && classifier.src_port() == 68 && classifier.dst_port() == 67)) { //DHCP packet
1822 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_HOST);
1823 } else {
1824 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1825 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
1826 }
1827 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1828 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1829 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1830 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1831 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
1832 }
1833 } else {
1834 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
1835 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
1836 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001837
Shad Ansari39739bc2018-09-13 21:38:37 +00001838 if (onu_id >= 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001839 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001840 }
1841 if (gemport_id >= 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001842 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001843 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001844 if (gemport_id >= 0 && port_no != 0) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001845 bcmos_fastlock_lock(&data_lock);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001846 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06001847 port_to_flows[port_no].insert(key.flow_id);
1848 flowid_to_gemport[key.flow_id] = gemport_id;
1849 }
1850 else
1851 {
1852 flowid_to_port[key.flow_id] = port_no;
1853 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001854 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001855 }
Shad Ansari39739bc2018-09-13 21:38:37 +00001856 if (priority_value >= 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001857 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
Shad Ansari39739bc2018-09-13 21:38:37 +00001858 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001859
1860 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001861 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001862 if (classifier.o_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001863 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_tpid 0x%04x\n", classifier.o_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05001864 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, o_tpid, classifier.o_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001865 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001866 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001867 if (classifier.o_vid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001868 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
1869 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001870 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001871 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001872 if (classifier.i_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001873 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_tpid 0x%04x\n", classifier.i_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05001874 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, i_tpid, classifier.i_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001875 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001876 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001877 if (classifier.i_vid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001878 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
1879 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001880 }
1881
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001882 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001883 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001884 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
1885 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001886 }
1887
1888 /*
1889 if (classifier.dst_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001890 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_mac, classifier.dst_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001891 }
1892
1893 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001894 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001895 }
1896 */
1897
1898 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001899 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
1900 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001901 }
1902
1903 /*
1904 if (classifier.dst_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001905 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_ip, classifier.dst_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001906 }
1907
1908 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001909 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001910 }
1911 */
1912
1913 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001914 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
1915 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001916 }
1917
1918 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001919 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
1920 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001921 }
1922
1923 if (!classifier.pkt_tag_type().empty()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001924 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001925 if (classifier.pkt_tag_type().compare("untagged") == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001926 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001927 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001928 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001929 single_tag = true;
1930
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001931 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
1932 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001933 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001934 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001935
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001936 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
1937 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001938 }
1939 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001940 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001941 }
1942
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001943 if (cfg.data.egress_intf.intf_type != BCMOLT_FLOW_INTERFACE_TYPE_HOST) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001944 const ::openolt::ActionCmd& cmd = action.cmd();
1945
1946 if (cmd.add_outer_tag()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001947 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
1948 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001949 }
1950
1951 if (cmd.remove_outer_tag()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001952 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
1953 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001954 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001955 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001956 if (cmd.trap_to_host()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001957 OPENOLT_LOG(INFO, openolt_log_id, "action trap-to-host\n");
Craig Lutgen19512312018-11-02 10:14:46 -05001958 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, cmds_bitmask, BCMBAL_ACTION_CMD_ID_TRAP_TO_HOST);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001959 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001960 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001961 if (action.o_vid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001962 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001963 o_vid = action.o_vid();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001964 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001965 }
1966
1967 if (action.o_pbits()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001968 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
1969 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001970 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001971 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001972 if (action.o_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001973 OPENOLT_LOG(INFO, openolt_log_id, "action o_tpid=0x%04x\n", action.o_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05001974 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, o_tpid, action.o_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001975 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001976 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001977 if (action.i_vid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001978 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
1979 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001980 }
1981
1982 if (action.i_pbits()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001983 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
1984 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001985 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001986 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001987 if (action.i_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001988 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_tpid=0x%04x\n", action.i_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05001989 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, i_tpid, action.i_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001990 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001991 */
1992 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001993 }
1994
Shad Ansari39739bc2018-09-13 21:38:37 +00001995 if ((access_intf_id >= 0) && (onu_id >= 0)) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001996 if(single_tag && ether_type == EAP_ETHER_TYPE) {
1997 tm_val.sched_id = (flow_type.compare(upstream) == 0) ? \
1998 get_default_tm_sched_id(network_intf_id, upstream) : \
1999 get_default_tm_sched_id(access_intf_id, downstream);
2000 tm_val.queue_id = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002001
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002002 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2003 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2004 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002005
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002006 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2007 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
2008 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2009 } else {
2010 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
2011 tm_val.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, downstream);
2012
2013 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2014 // Queue 0 on DS subscriber scheduler
2015 tm_val.queue_id = 0;
2016
2017 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2018 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2019 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2020
2021 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2022 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2023 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2024
2025 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2026 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
2027 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2028
2029 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2030 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2031 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2032 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_q_set_id, tm_q_set_id);
2033
2034 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2035 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2036 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2037 }
2038 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
2039 // NNI Scheduler ID
2040 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2041 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2042 // Queue 0 on NNI scheduler
2043 tm_val.queue_id = 0;
2044 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2045 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2046 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2047
2048 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2049 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2050 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2051
2052 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2053 /* Fetch TM QMP ID mapped to US NNI scheduler */
2054 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2055 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2056 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2057 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2058 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_q_set_id, tm_q_set_id);
2059
2060 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2061 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2062 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2063 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002064 }
Shad Ansari39739bc2018-09-13 21:38:37 +00002065 }
Shad Ansari06101952018-07-25 00:22:09 +00002066 }
2067
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002068 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
2069 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
2070#ifdef FLOW_CHECKER
2071 //Flow Checker, To avoid duplicate flow.
2072 if (flow_id_counters != 0) {
2073 bool b_duplicate_flow = false;
2074 for (int flowid=0; flowid < flow_id_counters; flowid++) {
2075 int flow_index = flow_id_data[flowid][0];
2076 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(flow_index, flow_id_data[flowid][1], ONU_ID)) && \
2077 (key.flow_type == flow_id_data[flowid][1]) && \
2078 (cfg.data.svc_port_id == get_flow_status(flow_index, flow_id_data[flowid][1], SVC_PORT_ID)) && \
2079 (cfg.data.priority == get_flow_status(flow_index, flow_id_data[flowid][1], PRIORITY)) && \
2080 (cfg.data.cookie == get_flow_status(flow_index, flow_id_data[flowid][1], COOKIE)) && \
2081 (cfg.data.ingress_intf.intf_type == get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_TYPE)) && \
2082 (cfg.data.ingress_intf.intf_id == get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_ID)) && \
2083 (cfg.data.egress_intf.intf_type == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_TYPE)) && \
2084 (cfg.data.egress_intf.intf_id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_ID)) && \
2085 (c_val.o_vid == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_VID)) && \
2086 (c_val.o_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_PBITS)) && \
2087 (c_val.i_vid == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_VID)) && \
2088 (c_val.i_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_PBITS)) && \
2089 (c_val.ether_type == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_ETHER_TYPE)) && \
2090 (c_val.ip_proto == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_IP_PROTO)) && \
2091 (c_val.src_port == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_SRC_PORT)) && \
2092 (c_val.dst_port == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_DST_PORT)) && \
2093 (c_val.pkt_tag_type == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_PKT_TAG_TYPE)) && \
2094 (cfg.data.egress_qos.type == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TYPE)) && \
2095 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_QUEUE_ID)) && \
2096 (cfg.data.egress_qos.tm_sched.id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TM_SCHED_ID)) && \
2097 (a_val.cmds_bitmask == get_flow_status(flowid, flow_id_data[flowid][1], ACTION_CMDS_BITMASK)) && \
2098 (a_val.o_vid == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_VID)) && \
2099 (a_val.i_vid == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_VID)) && \
2100 (a_val.o_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_PBITS)) && \
2101 (a_val.i_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_PBITS)) && \
2102 (cfg.data.state == get_flow_status(flowid, flow_id_data[flowid][1], STATE));
2103#ifdef SHOW_FLOW_PARAM
2104 // Flow Parameter
2105 FLOW_PARAM_LOG();
2106#endif
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002107
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002108 if (b_duplicate_flow) {
2109 FLOW_LOG(WARNING, "Flow duplicate", 0);
2110 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
2111 }
2112 }
2113 }
2114#endif
2115
2116 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2117 if (err) {
2118 FLOW_LOG(ERROR, "Flow add failed", err);
2119 return bcm_to_grpc_err(err, "flow add failed");
2120 } else {
2121 FLOW_LOG(INFO, "Flow add ok", err);
2122 bcmos_fastlock_lock(&data_lock);
2123 flow_id_data[flow_id_counters][0] = key.flow_id;
2124 flow_id_data[flow_id_counters][1] = key.flow_type;
2125 flow_id_counters += 1;
2126 bcmos_fastlock_unlock(&data_lock, 0);
2127 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04002128
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002129 return Status::OK;
2130}
2131
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002132Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
2133
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002134 bcmolt_flow_cfg cfg;
2135 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002136
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002137 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002138 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002139 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002140 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002141 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002142 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002143 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002144 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002145 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
2146 }
2147
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002148 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002149 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002150 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002151 flowid_to_gemport.erase(key.flow_id);
2152 port_to_flows[port_no].erase(key.flow_id);
2153 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
2154 }
2155 else
2156 {
2157 flowid_to_port.erase(key.flow_id);
2158 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002159 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002160
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002161 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002162
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002163 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002164 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002165 OPENOLT_LOG(ERROR, openolt_log_id, "Error %d while removing flow %d, %s\n",
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04002166 err, flow_id, flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002167 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
2168 }
2169
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002170 bcmos_fastlock_lock(&data_lock);
2171 for (int flowid=0; flowid < flow_id_counters; flowid++) {
2172 if (flow_id_data[flowid][0] == flow_id && flow_id_data[flowid][1] == key.flow_type) {
2173 flow_id_counters -= 1;
2174 for (int i=flowid; i < flow_id_counters; i++) {
2175 flow_id_data[i][0] = flow_id_data[i + 1][0];
2176 flow_id_data[i][1] = flow_id_data[i + 1][1];
2177 }
2178 break;
2179 }
2180 }
2181 bcmos_fastlock_unlock(&data_lock, 0);
2182
2183 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002184 return Status::OK;
2185}
2186
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002187bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
2188 bcmos_errno err;
2189 bcmolt_tm_sched_cfg tm_sched_cfg;
2190 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2191 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
2192
2193 // bcmbal_tm_sched_owner
2194 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2195
2196 /**< The output of the tm_sched object instance */
2197 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
2198
2199 if (direction.compare(upstream) == 0) {
2200 // In upstream it is NNI scheduler
2201 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
2202 } else if (direction.compare(downstream) == 0) {
2203 // In downstream it is PON scheduler
2204 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2205 }
2206
2207 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2208
2209 // bcmbal_tm_sched_type
2210 // set the deafult policy to strict priority
2211 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2212
2213 // num_priorities: Max number of strict priority scheduling elements
2214 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
2215
2216 // bcmbal_tm_shaping
2217 uint32_t cir = 1000000;
2218 uint32_t pir = 1000000;
2219 uint32_t burst = 65536;
2220 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in %s pir=%u, burst=%u\n",
2221 direction.c_str(), pir, burst);
2222 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2223 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2224 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2225 // BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2226 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2227 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
2228
2229 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2230 if (err) {
2231 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err %d\n", \
2232 direction.c_str(), tm_sched_key.id, intf_id, err);
2233 return err;
2234 }
2235
2236 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2237 direction.c_str(), tm_sched_key.id, intf_id);
2238 return BCM_ERR_OK;
2239}
2240
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002241bcmos_errno CreateSched(std::string direction, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t port_no,
2242 uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
2243 tech_profile::SchedulingPolicy sched_policy, tech_profile::TrafficShapingInfo tf_sh_info) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002244
2245 bcmos_errno err;
2246
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002247 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002248 bcmolt_tm_sched_cfg tm_sched_cfg;
2249 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2250 tm_sched_key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002251
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002252 // bcmbal_tm_sched_owner
2253 // In downstream it is sub_term scheduler
2254 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002255
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002256 /**< The output of the tm_sched object instance */
2257 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002258
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002259 // bcmbal_tm_sched_parent
2260 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2261 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
2262 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_param.u.priority.priority, priority);
2263 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
2264 be achieved using the' virtual' type of attachment.
2265 tm_sched_owner.u.sub_term.intf_id = intf_id;
2266 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2267 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002268
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002269 // bcmbal_tm_sched_type
2270 // set the deafult policy to strict priority
2271 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002272
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002273 // num_priorities: Max number of strict priority scheduling elements
2274 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002275
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002276 // bcmbal_tm_shaping
2277 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2278 uint32_t cir = tf_sh_info.cir();
2279 uint32_t pir = tf_sh_info.pir();
2280 uint32_t burst = tf_sh_info.pbs();
2281 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2282 cir, pir, burst);
2283 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2284 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2285 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2286 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2287 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2288 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002289 }
2290
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002291 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002292 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002293 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
2294intf_id %d, onu_id %d, uni_id %d, port_no %u\n", tm_sched_key.id, intf_id, onu_id, \
2295 uni_id, port_no);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002296 return err;
2297 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002298 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2299uni_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 -08002300
2301 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002302 bcmolt_itupon_alloc_cfg cfg;
2303 bcmolt_itupon_alloc_key key = { };
2304 key.pon_ni = intf_id;
2305 key.alloc_id = alloc_id;
2306 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
2307 int pir_bw = tf_sh_info.pir();
2308 int cir_bw = tf_sh_info.cir();
2309 //offset to match bandwidth granularity
2310 int offset_pir_bw = pir_bw%bw_granularity;
2311 int offset_cir_bw = cir_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002312
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002313 pir_bw = pir_bw - offset_pir_bw;
2314 cir_bw = cir_bw - offset_cir_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002315
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002316 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002317
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002318 switch (additional_bw) {
2319 case 2: //AdditionalBW_BestEffort
2320 if (pir_bw == 0) {
2321 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2322%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2323 } else if (pir_bw < cir_bw) {
2324 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2325bandwidth (%d)\n", pir_bw, cir_bw);
2326 return BCM_ERR_PARM;
2327 } else if (pir_bw == cir_bw) {
2328 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2329bandwidth for additional bandwidth eligibility of type best_effort\n");
2330 return BCM_ERR_PARM;
2331 }
2332 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2333 break;
2334 case 1: //AdditionalBW_NA
2335 if (pir_bw == 0) {
2336 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2337%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2338 return BCM_ERR_PARM;
2339 } else if (cir_bw == 0) {
2340 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2341additional bandwidth eligibility of type Non-Assured (NA)\n");
2342 return BCM_ERR_PARM;
2343 } else if (pir_bw < cir_bw) {
2344 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2345bandwidth (%d)\n", pir_bw, cir_bw);
2346 return BCM_ERR_PARM;
2347 } else if (pir_bw == cir_bw) {
2348 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2349bandwidth for additional bandwidth eligibility of type non_assured\n");
2350 return BCM_ERR_PARM;
2351 }
2352 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2353 break;
2354 case 0: //AdditionalBW_None
2355 if (pir_bw == 0) {
2356 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
235716000 bytes/sec\n");
2358 return BCM_ERR_PARM;
2359 } else if (cir_bw == 0) {
2360 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2361for additional bandwidth eligibility of type None\n");
2362 return BCM_ERR_PARM;
2363 } else if (pir_bw > cir_bw) {
2364 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2365for additional bandwidth eligibility of type None\n");
2366 OPENOLT_LOG(ERROR, openolt_log_id, "set Maximum bandwidth (%d) to Guaranteed \
2367bandwidth in None eligibility\n", pir_bw);
2368 cir_bw = pir_bw;
2369 } else if (pir_bw < cir_bw) {
2370 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2371bandwidth (%d)\n", pir_bw, cir_bw);
2372 OPENOLT_LOG(ERROR, openolt_log_id, "set Maximum bandwidth (%d) to Guaranteed \
2373bandwidth in None eligibility\n", pir_bw);
2374 cir_bw = pir_bw;
2375 }
2376 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2377 break;
2378 default:
2379 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002380 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002381 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2382 in a fine granularity. */
2383 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
2384 /* Fixed Bandwidth with no critical requirement of shaping */
2385 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, 0);
2386 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
2387 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, cir_bw);
2388 /* Maximum allocated bandwidth allowed for this alloc ID */
2389 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
2390 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
2391 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
2392 for skipped allocations during quiet window */
2393 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2394 /**< Allocation Profile index for CBR non-RT Bandwidth */
2395 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2396 /**< Allocation Profile index for CBR RT Bandwidth */
2397 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2398 /**< Alloc ID Weight used in case of Extended DBA mode */
2399 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2400 /**< Alloc ID Priority used in case of Extended DBA mode */
2401 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2402 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002403
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002404 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002405 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002406 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2407port_no %u, alloc_id %d, err %d\n", intf_id, onu_id,uni_id,port_no,alloc_id, err);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002408 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002409 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002410 OPENOLT_LOG(INFO, openolt_log_id, "Create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d, port_no %u, \
2411alloc_id %d\n", intf_id,onu_id,uni_id,port_no,alloc_id);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002412 }
2413
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002414 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002415}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002416
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002417Status CreateTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2418 uint32_t intf_id = traffic_scheds->intf_id();
2419 uint32_t onu_id = traffic_scheds->onu_id();
2420 uint32_t uni_id = traffic_scheds->uni_id();
2421 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002422 std::string direction;
2423 unsigned int alloc_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002424 tech_profile::SchedulerConfig sched_config;
2425 tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002426 uint32_t priority;
2427 uint32_t weight;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002428 tech_profile::SchedulingPolicy sched_policy;
2429 tech_profile::TrafficShapingInfo traffic_shaping_info;
2430 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002431
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002432 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2433 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002434
2435 direction = GetDirection(traffic_sched.direction());
2436 if (direction.compare("direction-not-supported") == 0)
2437 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2438
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002439 alloc_id = traffic_sched.alloc_id();
2440 sched_config = traffic_sched.scheduler();
2441 additional_bw = sched_config.additional_bw();
2442 priority = sched_config.priority();
2443 weight = sched_config.weight();
2444 sched_policy = sched_config.sched_policy();
2445 traffic_shaping_info = traffic_sched.traffic_shaping_info();
2446 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
2447 sched_policy, traffic_shaping_info);
2448 if (err) {
2449 return bcm_to_grpc_err(err, "Failed to create scheduler");
2450 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002451 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002452 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002453}
Jonathan Davis70c21812018-07-19 15:32:10 -04002454
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002455bcmos_errno RemoveSched(int intf_id, int onu_id, int uni_id, int alloc_id, std::string direction) {
Jonathan Davis70c21812018-07-19 15:32:10 -04002456
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002457 bcmos_errno err;
Jonathan Davis70c21812018-07-19 15:32:10 -04002458
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002459 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002460 bcmolt_itupon_alloc_cfg cfg;
2461 bcmolt_itupon_alloc_key key = { };
2462 key.pon_ni = intf_id;
2463 key.alloc_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002464
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002465 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
2466 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2467 if (err) {
2468 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler sched, direction = %s, intf_id %d, alloc_id %d, err %d\n", \
2469 direction.c_str(), intf_id, alloc_id, err);
2470 return err;
2471 }
2472 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, intf_id %d, alloc_id %d\n", \
2473 direction.c_str(), intf_id, alloc_id);
2474 } else if (direction == downstream) {
2475 bcmolt_tm_sched_cfg cfg;
2476 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002477
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002478 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction)) {
2479 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
2480 } else {
2481 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2482 return BCM_ERR_OK;
2483 }
2484 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2485 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2486 if (err) {
2487 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, id %d, intf_id %d, onu_id %d\n", \
2488 direction.c_str(), key.id, intf_id, onu_id);
2489 return err;
2490 }
2491 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d\n", \
2492 direction.c_str(), key.id, intf_id, onu_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002493 }
2494
2495 free_tm_sched_id(intf_id, onu_id, uni_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002496 return BCM_ERR_OK;
2497}
2498
2499Status RemoveTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2500 uint32_t intf_id = traffic_scheds->intf_id();
2501 uint32_t onu_id = traffic_scheds->onu_id();
2502 uint32_t uni_id = traffic_scheds->uni_id();
2503 std::string direction;
2504 bcmos_errno err;
2505
2506 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2507 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002508
2509 direction = GetDirection(traffic_sched.direction());
2510 if (direction.compare("direction-not-supported") == 0)
2511 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2512
2513 int alloc_id = traffic_sched.alloc_id();
2514 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002515 if (err) {
2516 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2517 }
2518 }
2519 return Status::OK;
2520}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002521
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002522bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2523 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002524 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002525 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2526 bcmolt_tm_qmp_key tm_qmp_key;
2527 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002528
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002529 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2530 if (tm_qmp_id == -1) {
2531 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 -08002532 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002533
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002534 tm_qmp_key.id = tm_qmp_id;
2535 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2536 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2537 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002538
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002539 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2540 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2541 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
2542 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2543 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002544
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002545 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002546 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002547 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, id %d\n", \
2548 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002549 return err;
2550 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002551
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002552 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2553 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002554 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002555}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002556
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002557bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2558 bcmos_errno err;
2559 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2560 bcmolt_tm_qmp_key tm_qmp_key;
2561 tm_qmp_key.id = tm_qmp_id;
2562
2563 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2564 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2565 if (err) {
2566 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, id %d\n", \
2567 tm_qmp_key.id);
2568 return err;
2569 }
2570
2571 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2572 tm_qmp_key.id);
2573 return BCM_ERR_OK;
2574}
2575
2576bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2577 bcmos_errno err;
2578
2579 /* Create 4 Queues on given PON/NNI scheduler */
2580 for (int queue_id = 0; queue_id < 4; queue_id++) {
2581 bcmolt_tm_queue_cfg tm_queue_cfg;
2582 bcmolt_tm_queue_key tm_queue_key = {};
2583 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2584 tm_queue_key.id = queue_id;
2585 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE)
2586 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2587 else
2588 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2589
2590 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2591 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2592 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2593
2594 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2595 if (err) {
2596 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s tm queue, id %d, sched_id %d, tm_q_set_id %d\n", \
2597 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2598 return err;
2599 }
2600
2601 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2602 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2603 }
2604 return BCM_ERR_OK;
2605}
2606
2607bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t priority,
2608 uint32_t gemport_id) {
2609 bcmos_errno err;
2610 bcmolt_tm_queue_cfg cfg;
2611 bcmolt_tm_queue_key key = { };
2612 OPENOLT_LOG(INFO, openolt_log_id, "creating %s queue. access_intf_id = %d, onu_id = %d, uni_id = %d \
2613gemport_id = %d\n", direction.c_str(), access_intf_id, onu_id, uni_id, gemport_id);
2614
2615 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2616 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
2617
2618 if (priority > 7) {
2619 return BCM_ERR_RANGE;
2620 }
2621
2622 /* FIXME: The upstream queues have to be created once only.
2623 The upstream queues on the NNI scheduler are shared by all subscribers.
2624 When the first scheduler comes in, the queues get created, and are re-used by all others.
2625 Also, these queues should be present until the last subscriber exits the system.
2626 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2627
2628 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2629 for each GEM in TECH PROFILE */
2630 key.id = queue_id_list[priority];
2631
2632 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2633 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2634 key.id = 0;
2635 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2636 }
2637 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2638 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2639 }
2640 else {
2641 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2642 }
2643
2644 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2645
2646 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2647 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
2648
2649 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2650 if (err) {
2651 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, id %d, \
2652sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err %d\n", \
2653 direction.c_str(), key.id, key.sched_id, key.tm_q_set_id, access_intf_id, onu_id, uni_id, err);
2654 return err;
2655 }
2656
2657 OPENOLT_LOG(INFO, openolt_log_id, "Created tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2658intf_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);
2659 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002660}
2661
2662Status CreateTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2663 uint32_t intf_id = traffic_queues->intf_id();
2664 uint32_t onu_id = traffic_queues->onu_id();
2665 uint32_t uni_id = traffic_queues->uni_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002666 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002667 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002668 bcmos_errno err;
2669
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002670 qos_type = (traffic_queues->traffic_queues_size() > 1) ? \
2671 BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE : BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE;
2672
2673 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2674 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2675 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2676 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2677 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
2678
2679 direction = GetDirection(traffic_queue.direction());
2680 if (direction.compare("direction-not-supported") == 0)
2681 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2682
2683 queues_priority_q[i] = traffic_queue.priority();
2684 queues_pbit_map[i] = traffic_queue.pbit_map();
2685 }
2686
2687 std::vector<uint32_t> tmq_map_profile(8, 0);
2688 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2689 queues_priority_q, COUNT_OF(queues_priority_q));
2690 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2691 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
2692
2693 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2694 if (tm_qmp_id == -1) {
2695 CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2696 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2697 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2698 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2699 }
2700 }
2701
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002702 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2703 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002704
2705 direction = GetDirection(traffic_queue.direction());
2706 if (direction.compare("direction-not-supported") == 0)
2707 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2708
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002709 err = CreateQueue(direction, intf_id, onu_id, uni_id, traffic_queue.priority(), traffic_queue.gemport_id());
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002710
Girish Gowdruf26cf882019-05-01 23:47:58 -07002711 // If the queue exists already, lets not return failure and break the loop.
2712 if (err && err != BCM_ERR_ALREADY) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002713 return bcm_to_grpc_err(err, "Failed to create queue");
2714 }
2715 }
2716 return Status::OK;
2717}
2718
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002719bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t priority,
2720 uint32_t gemport_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002721 bcmolt_tm_queue_cfg cfg;
2722 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002723 bcmos_errno err;
2724
2725 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002726 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction)) {
2727 key.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
2728 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002729 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002730 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 -08002731 return BCM_ERR_OK;
2732 }
2733 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002734 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2735 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002736 return BCM_ERR_OK;
2737 }
2738
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002739 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2740 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2741 // Reset the queue id to 0 when using fixed queue.
2742 key.id = 0;
2743 }
2744 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2745 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2746 }
2747 else {
2748 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2749 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002750
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002751 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2752 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002753 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002754 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, id %d, sched_id %d, \
2755tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d\n",
2756 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 -08002757 return err;
2758 }
2759
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002760 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2761intf_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 -08002762
2763 return BCM_ERR_OK;
2764}
2765
2766Status RemoveTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2767 uint32_t intf_id = traffic_queues->intf_id();
2768 uint32_t onu_id = traffic_queues->onu_id();
2769 uint32_t uni_id = traffic_queues->uni_id();
2770 uint32_t port_no = traffic_queues->port_no();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002771 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002772 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002773 bcmos_errno err;
2774
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002775 qos_type = (traffic_queues->traffic_queues_size() > 1) ? \
2776 BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE : BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE;
2777
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002778 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2779 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002780
2781 direction = GetDirection(traffic_queue.direction());
2782 if (direction.compare("direction-not-supported") == 0)
2783 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2784
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002785 err = RemoveQueue(direction, intf_id, onu_id, uni_id, traffic_queue.priority(), traffic_queue.gemport_id());
2786 if (err) {
2787 return bcm_to_grpc_err(err, "Failed to remove queue");
2788 }
Jonathan Davis70c21812018-07-19 15:32:10 -04002789 }
2790
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002791 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))) {
2792 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2793 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
2794
2795 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
2796 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
2797 RemoveTrafficQueueMappingProfile(tm_qmp_id);
2798 }
2799 }
Jonathan Davis70c21812018-07-19 15:32:10 -04002800 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04002801}