blob: a2da56d5ee159eec9b3d2f4b09c2cb5527da6579 [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>
Jason Huangd33b4d82019-05-15 18:22:57 +080027#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{
Jason Huangd33b4d82019-05-15 18:22:57 +080039#include <bcmolt_api.h>
40#include <bcmolt_host_api.h>
41#include <bcmolt_api_model_supporting_enums.h>
42#include <bal_version.h>
43#include <bcmolt_api_conn_mgr.h>
44//CLI header files
45#include <bcmcli_session.h>
46#include <bcmcli.h>
47#include <bcm_api_cli.h>
48#include <bcmos_common.h>
49#include <bcm_config.h>
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -040050// FIXME : dependency problem
51// #include <bcm_common_gpon.h>
Nicolas Palpacuer967438f2018-09-07 14:41:54 -040052// #include <bcm_dev_log_task.h>
Shad Ansarib7b0ced2018-05-11 21:53:32 +000053}
Nicolas Palpacuer967438f2018-09-07 14:41:54 -040054dev_log_id openolt_log_id = bcm_dev_log_id_register("OPENOLT", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
55dev_log_id omci_log_id = bcm_dev_log_id_register("OMCI", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
56
Craig Lutgen88a22ad2018-10-04 12:30:46 -050057#define BAL_RSC_MANAGER_BASE_TM_SCHED_ID 16384
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080058#define MAX_TM_QUEUE_ID 8192
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +080059#define MAX_TM_QMP_ID 16
60#define TMQ_MAP_PROFILE_SIZE 8
61#define MAX_TM_SCHED_ID 1023
62#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 -080063#define EAP_ETHER_TYPE 34958
Jason Huangb6843dc2019-07-22 17:46:06 +080064#define XGS_BANDWIDTH_GRANULARITY 16000
65#define GPON_BANDWIDTH_GRANULARITY 32000
66#define FILL_ARRAY(ARRAY,START,END,VALUE) for(int i=START;i<END;ARRAY[i++]=VALUE);
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +080067#define COUNT_OF(array) (sizeof(array) / sizeof(array[0]))
Jason Huangb6843dc2019-07-22 17:46:06 +080068
69#define GET_FLOW_INTERFACE_TYPE(type) \
70 (type == BCMOLT_FLOW_INTERFACE_TYPE_PON) ? "PON" : \
71 (type == BCMOLT_FLOW_INTERFACE_TYPE_NNI) ? "NNI" : \
72 (type == BCMOLT_FLOW_INTERFACE_TYPE_HOST) ? "HOST" : "unknown"
73#define GET_PKT_TAG_TYPE(type) \
74 (type == BCMOLT_PKT_TAG_TYPE_UNTAGGED) ? "UNTAG" : \
75 (type == BCMOLT_PKT_TAG_TYPE_SINGLE_TAG) ? "SINGLE_TAG" : \
76 (type == BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG) ? "DOUBLE_TAG" : "unknown"
Nicolas Palpacuer967438f2018-09-07 14:41:54 -040077
Craig Lutgen88a22ad2018-10-04 12:30:46 -050078static unsigned int num_of_nni_ports = 0;
79static unsigned int num_of_pon_ports = 0;
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +080080static std::string intf_technologies[MAX_SUPPORTED_PON];
Craig Lutgen88a22ad2018-10-04 12:30:46 -050081static const std::string UNKNOWN_TECH("unknown");
Craig Lutgenb2601f02018-10-23 13:04:31 -050082static const std::string MIXED_TECH("mixed");
83static std::string board_technology(UNKNOWN_TECH);
Jason Huangd33b4d82019-05-15 18:22:57 +080084static std::string chip_family(UNKNOWN_TECH);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -080085static unsigned int OPENOLT_FIELD_LEN = 200;
Jason Huangb6843dc2019-07-22 17:46:06 +080086static std::string firmware_version = "Openolt.2019.07.01";
Nicolas Palpacuerdff96792018-09-06 14:59:32 -040087
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +080088const uint32_t tm_upstream_sched_id_start = (MAX_SUPPORTED_PON == 16 ? \
89 MAX_TM_SCHED_ID-3 : MAX_TM_SCHED_ID-9);
90const uint32_t tm_downstream_sched_id_start = (MAX_SUPPORTED_PON == 16 ? \
91 tm_upstream_sched_id_start-16 : tm_upstream_sched_id_start-64);
92
93/* Max Queue ID supported is 7 so based on priority_q configured for GEMPORTS
94in TECH PROFILE respective Queue ID from this list will be used for both
95US and DS Queues*/
96const uint32_t queue_id_list[8] = {0, 1, 2, 3, 4, 5, 6, 7};
97
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -070098const std::string upstream = "upstream";
99const std::string downstream = "downstream";
Jason Huangd33b4d82019-05-15 18:22:57 +0800100bcmolt_oltid dev_id = 0;
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +0800101
Jason Huangd33b4d82019-05-15 18:22:57 +0800102/* Current session */
103static bcmcli_session *current_session;
104static bcmcli_entry *api_parent_dir;
105bcmos_bool status_bcm_cli_quit = BCMOS_FALSE;
106bcmos_task bal_cli_thread;
107const char *bal_cli_thread_name = "bal_cli_thread";
Jason Huangb6843dc2019-07-22 17:46:06 +0800108uint16_t flow_id_counters = 0;
109int flow_id_data[16384][2];
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700110
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +0800111/* QOS Type has been pre-defined as Fixed Queue but it will be updated based on number of GEMPORTS
112 associated for a given subscriber. If GEM count = 1 for a given subscriber, qos_type will be Fixed Queue
113 else Priority to Queue */
114bcmolt_egress_qos_type qos_type = BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE;
115
Shad Ansariedef2132018-08-10 22:14:50 +0000116State state;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400117
Craig Lutgen967a1d02018-11-27 10:41:51 -0600118static std::map<uint32_t, uint32_t> flowid_to_port; // For mapping upstream flows to logical ports
119static std::map<uint32_t, uint32_t> flowid_to_gemport; // For mapping downstream flows into gemports
120static 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 -0800121
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +0800122/* This represents the Key to 'sched_map' map.
123 Represents (pon_intf_id, onu_id, uni_id, direction) */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800124typedef std::tuple<uint32_t, uint32_t, uint32_t, std::string> sched_map_key_tuple;
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +0800125/* 'sched_map' maps sched_map_key_tuple to DBA (Upstream) or
126 Subscriber (Downstream) Scheduler ID */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800127static std::map<sched_map_key_tuple, int> sched_map;
128
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +0800129/* This represents the Key to 'sched_qmp_id_map' map.
130Represents (sched_id, pon_intf_id, onu_id, uni_id) */
131typedef std::tuple<uint32_t, uint32_t, uint32_t, uint32_t> sched_qmp_id_map_key_tuple;
132/* 'sched_qmp_id_map' maps sched_qmp_id_map_key_tuple to TM Queue Mapping Profile ID */
133static std::map<sched_qmp_id_map_key_tuple, int> sched_qmp_id_map;
134/* 'qmp_id_to_qmp_map' maps TM Queue Mapping Profile ID to TM Queue Mapping Profile */
135static std::map<int, std::vector < uint32_t > > qmp_id_to_qmp_map;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800136
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800137std::bitset<MAX_TM_SCHED_ID> tm_sched_bitset;
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +0800138std::bitset<MAX_TM_QMP_ID> tm_qmp_bitset;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800139
140static bcmos_fastlock data_lock;
Craig Lutgen967a1d02018-11-27 10:41:51 -0600141
142#define MIN_ALLOC_ID_GPON 256
143#define MIN_ALLOC_ID_XGSPON 1024
144
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800145static bcmos_errno CreateSched(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
146 uint32_t port_no, uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, \
147 uint32_t priority, tech_profile::SchedulingPolicy sched_policy,
148 tech_profile::TrafficShapingInfo traffic_shaping_info);
Jason Huangb6843dc2019-07-22 17:46:06 +0800149static 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 -0800150static bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
151 uint32_t priority, uint32_t gemport_id);
152static bcmos_errno RemoveQueue(std::string direction, int intf_id, int onu_id, int uni_id, uint32_t port_no, int alloc_id);
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +0800153static bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction);
154static bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction);
Shad Ansari627b5782018-08-13 22:49:32 +0000155
Jason Huangd33b4d82019-05-15 18:22:57 +0800156uint16_t get_dev_id(void) {
157 return dev_id;
158}
159
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800160/**
161* Returns the default NNI (Upstream direction) or PON (Downstream direction) scheduler
162* Every NNI port and PON port have default scheduler.
163* The NNI0 default scheduler ID is 18432, and NNI1 is 18433 and so on.
164* Similarly, PON0 default scheduler ID is 16384. PON1 is 16385 and so on.
165*
166* @param intf_id NNI or PON interface ID
167* @param direction "upstream" or "downstream"
168*
169* @return default scheduler ID for the given interface.
170*/
171static inline int get_default_tm_sched_id(int intf_id, std::string direction) {
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700172 if (direction.compare(upstream) == 0) {
173 return tm_upstream_sched_id_start + intf_id;
174 } else if (direction.compare(downstream) == 0) {
175 return tm_downstream_sched_id_start + intf_id;
176 }
177 else {
Jason Huangb6843dc2019-07-22 17:46:06 +0800178 OPENOLT_LOG(ERROR, openolt_log_id, "invalid direction - %s\n", direction.c_str());
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700179 return 0;
180 }
181}
182
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800183/**
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800184* Gets a unique tm_sched_id for a given intf_id, onu_id, uni_id, gemport_id, direction
185* The tm_sched_id is locally cached in a map, so that it can rendered when necessary.
186* VOLTHA replays whole configuration on OLT reboot, so caching locally is not a problem
187*
188* @param intf_id NNI or PON intf ID
189* @param onu_id ONU ID
190* @param uni_id UNI ID
191* @param gemport_id GEM Port ID
192* @param direction Upstream or downstream
193*
194* @return tm_sched_id
195*/
196uint32_t get_tm_sched_id(int pon_intf_id, int onu_id, int uni_id, std::string direction) {
197 sched_map_key_tuple key(pon_intf_id, onu_id, uni_id, direction);
198 int sched_id = -1;
199
200 std::map<sched_map_key_tuple, int>::const_iterator it = sched_map.find(key);
201 if (it != sched_map.end()) {
202 sched_id = it->second;
203 }
204 if (sched_id != -1) {
205 return sched_id;
206 }
207
208 bcmos_fastlock_lock(&data_lock);
209 // Complexity of O(n). Is there better way that can avoid linear search?
210 for (sched_id = 0; sched_id < MAX_TM_SCHED_ID; sched_id++) {
211 if (tm_sched_bitset[sched_id] == 0) {
212 tm_sched_bitset[sched_id] = 1;
213 break;
214 }
215 }
216 bcmos_fastlock_unlock(&data_lock, 0);
217
218 if (sched_id < MAX_TM_SCHED_ID) {
219 bcmos_fastlock_lock(&data_lock);
220 sched_map[key] = sched_id;
221 bcmos_fastlock_unlock(&data_lock, 0);
222 return sched_id;
223 } else {
224 return -1;
225 }
226}
227
228/**
229* Free tm_sched_id for a given intf_id, onu_id, uni_id, gemport_id, direction
230*
231* @param intf_id NNI or PON intf ID
232* @param onu_id ONU ID
233* @param uni_id UNI ID
234* @param gemport_id GEM Port ID
235* @param direction Upstream or downstream
236*/
237void free_tm_sched_id(int pon_intf_id, int onu_id, int uni_id, std::string direction) {
238 sched_map_key_tuple key(pon_intf_id, onu_id, uni_id, direction);
239 std::map<sched_map_key_tuple, int>::const_iterator it;
240 bcmos_fastlock_lock(&data_lock);
241 it = sched_map.find(key);
242 if (it != sched_map.end()) {
243 tm_sched_bitset[it->second] = 0;
244 sched_map.erase(it);
245 }
246 bcmos_fastlock_unlock(&data_lock, 0);
247}
248
249bool is_tm_sched_id_present(int pon_intf_id, int onu_id, int uni_id, std::string direction) {
250 sched_map_key_tuple key(pon_intf_id, onu_id, uni_id, direction);
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +0800251 std::map<sched_map_key_tuple, int>::const_iterator it = sched_map.find(key);
252 if (it != sched_map.end()) {
253 return true;
254 }
255 return false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800256}
257
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +0800258/**
259* Check whether given two tm qmp profiles are equal or not
260*
261* @param tmq_map_profileA <vector> TM QUEUE MAPPING PROFILE
262* @param tmq_map_profileB <vector> TM QUEUE MAPPING PROFILE
263*
264* @return boolean, true if given tmq_map_profiles are equal else false
265*/
266
267bool check_tm_qmp_equality(std::vector<uint32_t> tmq_map_profileA, std::vector<uint32_t> tmq_map_profileB) {
268 for (uint32_t i = 0; i < TMQ_MAP_PROFILE_SIZE; i++) {
269 if (tmq_map_profileA[i] != tmq_map_profileB[i]) {
270 return false;
271 }
272 }
273 return true;
274}
275
276/**
277* Modifies given queues_pbit_map to parsable format
278* e.g: Modifes "0b00000101" to "10100000"
279*
280* @param queues_pbit_map PBIT MAP configured for each GEM in TECH PROFILE
281* @param size Queue count
282*
283* @return string queues_pbit_map
284*/
285std::string* get_valid_queues_pbit_map(std::string *queues_pbit_map, uint32_t size) {
286 for(uint32_t i=0; i < size; i++) {
287 /* Deletes 2 characters from index number 0 */
288 queues_pbit_map[i].erase(0, 2);
289 std::reverse(queues_pbit_map[i].begin(), queues_pbit_map[i].end());
290 }
291 return queues_pbit_map;
292}
293
294/**
295* Creates TM QUEUE MAPPING PROFILE for given queues_pbit_map and queues_priority_q
296*
297* @param queues_pbit_map PBIT MAP configured for each GEM in TECH PROFILE
298* @param queues_priority_q PRIORITY_Q configured for each GEM in TECH PROFILE
299* @param size Queue count
300*
301* @return <vector> TM QUEUE MAPPING PROFILE
302*/
303std::vector<uint32_t> get_tmq_map_profile(std::string *queues_pbit_map, uint32_t *queues_priority_q, uint32_t size) {
304 std::vector<uint32_t> tmq_map_profile(8,0);
305
306 for(uint32_t i=0; i < size; i++) {
307 for (uint32_t j = 0; j < queues_pbit_map[i].size(); j++) {
308 if (queues_pbit_map[i][j]=='1') {
309 tmq_map_profile.at(j) = queue_id_list[queues_priority_q[i]];
310 }
311 }
312 }
313 return tmq_map_profile;
314}
315
316/**
317* Gets corresponding tm_qmp_id for a given tmq_map_profile
318*
319* @param <vector> TM QUEUE MAPPING PROFILE
320*
321* @return tm_qmp_id
322*/
323int get_tm_qmp_id(std::vector<uint32_t> tmq_map_profile) {
324 int tm_qmp_id = -1;
325
326 std::map<int, std::vector < uint32_t > >::const_iterator it = qmp_id_to_qmp_map.begin();
327 while(it != qmp_id_to_qmp_map.end()) {
328 if(check_tm_qmp_equality(tmq_map_profile, it->second)) {
329 tm_qmp_id = it->first;
330 break;
331 }
332 it++;
333 }
334 return tm_qmp_id;
335}
336
337/**
338* Updates sched_qmp_id_map with given sched_id, pon_intf_id, onu_id, uni_id, tm_qmp_id
339*
340* @param upstream/downstream sched_id
341* @param PON intf ID
342* @param onu_id ONU ID
343* @param uni_id UNI ID
344* @param tm_qmp_id TM QUEUE MAPPING PROFILE ID
345*/
346void update_sched_qmp_id_map(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, \
347 uint32_t uni_id, int tm_qmp_id) {
348 bcmos_fastlock_lock(&data_lock);
349 sched_qmp_id_map_key_tuple key(sched_id, pon_intf_id, onu_id, uni_id);
350 sched_qmp_id_map.insert(make_pair(key, tm_qmp_id));
351 bcmos_fastlock_unlock(&data_lock, 0);
352}
353
354/**
355* Gets corresponding tm_qmp_id for a given sched_id, pon_intf_id, onu_id, uni_id
356*
357* @param upstream/downstream sched_id
358* @param PON intf ID
359* @param onu_id ONU ID
360* @param uni_id UNI ID
361*
362* @return tm_qmp_id
363*/
364int get_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id) {
365 sched_qmp_id_map_key_tuple key(sched_id, pon_intf_id, onu_id, uni_id);
366 int tm_qmp_id = -1;
367
368 std::map<sched_qmp_id_map_key_tuple, int>::const_iterator it = sched_qmp_id_map.find(key);
369 if (it != sched_qmp_id_map.end()) {
370 tm_qmp_id = it->second;
371 }
372 return tm_qmp_id;
373}
374
375/**
376* Gets a unique tm_qmp_id for a given tmq_map_profile
377* The tm_qmp_id is locally cached in a map, so that it can be rendered when necessary.
378* VOLTHA replays whole configuration on OLT reboot, so caching locally is not a problem
379*
380* @param upstream/downstream sched_id
381* @param PON intf ID
382* @param onu_id ONU ID
383* @param uni_id UNI ID
384* @param <vector> TM QUEUE MAPPING PROFILE
385*
386* @return tm_qmp_id
387*/
388int get_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id, \
389 std::vector<uint32_t> tmq_map_profile) {
390 int tm_qmp_id;
391
392 bcmos_fastlock_lock(&data_lock);
393 /* Complexity of O(n). Is there better way that can avoid linear search? */
394 for (tm_qmp_id = 0; tm_qmp_id < MAX_TM_QMP_ID; tm_qmp_id++) {
395 if (tm_qmp_bitset[tm_qmp_id] == 0) {
396 tm_qmp_bitset[tm_qmp_id] = 1;
397 break;
398 }
399 }
400 bcmos_fastlock_unlock(&data_lock, 0);
401
402 if (tm_qmp_id < MAX_TM_QMP_ID) {
403 bcmos_fastlock_lock(&data_lock);
404 qmp_id_to_qmp_map.insert(make_pair(tm_qmp_id, tmq_map_profile));
405 bcmos_fastlock_unlock(&data_lock, 0);
406 update_sched_qmp_id_map(sched_id, pon_intf_id, onu_id, uni_id, tm_qmp_id);
407 return tm_qmp_id;
408 } else {
409 return -1;
410 }
411}
412
413/**
414* Free tm_qmp_id for a given sched_id, pon_intf_id, onu_id, uni_id
415*
416* @param upstream/downstream sched_id
417* @param PON intf ID
418* @param onu_id ONU ID
419* @param uni_id UNI ID
420* @param tm_qmp_id TM QUEUE MAPPING PROFILE ID
421*
422* @return boolean, true if no more reference for TM QMP else false
423*/
424bool free_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, \
425 uint32_t uni_id, int tm_qmp_id) {
426 bool result;
427 sched_qmp_id_map_key_tuple key(sched_id, pon_intf_id, onu_id, uni_id);
428 std::map<sched_qmp_id_map_key_tuple, int>::const_iterator it = sched_qmp_id_map.find(key);
429 bcmos_fastlock_lock(&data_lock);
430 if (it != sched_qmp_id_map.end()) {
431 sched_qmp_id_map.erase(it);
432 }
433 bcmos_fastlock_unlock(&data_lock, 0);
434
435 uint32_t tm_qmp_ref_count = 0;
436 std::map<sched_qmp_id_map_key_tuple, int>::const_iterator it2 = sched_qmp_id_map.begin();
437 while(it2 != sched_qmp_id_map.end()) {
438 if(it2->second == tm_qmp_id) {
439 tm_qmp_ref_count++;
440 }
441 it2++;
442 }
443
444 if (tm_qmp_ref_count == 0) {
445 std::map<int, std::vector < uint32_t > >::const_iterator it3 = qmp_id_to_qmp_map.find(tm_qmp_id);
446 if (it3 != qmp_id_to_qmp_map.end()) {
447 bcmos_fastlock_lock(&data_lock);
448 tm_qmp_bitset[tm_qmp_id] = 0;
449 qmp_id_to_qmp_map.erase(it3);
450 bcmos_fastlock_unlock(&data_lock, 0);
451 OPENOLT_LOG(INFO, openolt_log_id, "Reference count for tm qmp profile id %d is : %d. So clearing it\n", \
452 tm_qmp_id, tm_qmp_ref_count);
453 result = true;
454 }
455 } else {
456 OPENOLT_LOG(INFO, openolt_log_id, "Reference count for tm qmp profile id %d is : %d. So not clearing it\n", \
457 tm_qmp_id, tm_qmp_ref_count);
458 result = false;
459 }
460 return result;
461}
462
463/**
464* Returns Scheduler/Queue direction as string
465*
466* @param direction as specified in tech_profile.proto
467*/
468std::string GetDirection(int direction) {
469 switch (direction)
470 {
471 case tech_profile::Direction::UPSTREAM: return upstream;
472 case tech_profile::Direction::DOWNSTREAM: return downstream;
473 default: OPENOLT_LOG(ERROR, openolt_log_id, "direction-not-supported %d\n", direction);
474 return "direction-not-supported";
475 }
Shad Ansari627b5782018-08-13 22:49:32 +0000476}
477
Jason Huangb6843dc2019-07-22 17:46:06 +0800478inline const char *get_flow_acton_command(uint32_t command) {
479 char actions[200] = { };
480 char *s_actions_ptr = actions;
481 if (command & BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG) strcat(s_actions_ptr, "ADD_OUTER_TAG|");
482 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG) strcat(s_actions_ptr, "REMOVE_OUTER_TAG|");
483 if (command & BCMOLT_ACTION_CMD_ID_XLATE_OUTER_TAG) strcat(s_actions_ptr, "TRANSLATE_OUTER_TAG|");
484 if (command & BCMOLT_ACTION_CMD_ID_ADD_INNER_TAG) strcat(s_actions_ptr, "ADD_INNTER_TAG|");
485 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_INNER_TAG) strcat(s_actions_ptr, "REMOVE_INNER_TAG|");
486 if (command & BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG) strcat(s_actions_ptr, "TRANSLATE_INNER_TAG|");
487 if (command & BCMOLT_ACTION_CMD_ID_REMARK_OUTER_PBITS) strcat(s_actions_ptr, "REMOVE_OUTER_PBITS|");
488 if (command & BCMOLT_ACTION_CMD_ID_REMARK_INNER_PBITS) strcat(s_actions_ptr, "REMAKE_INNER_PBITS|");
489 return s_actions_ptr;
490}
491
Jason Huang88795222019-06-13 19:28:44 +0800492char* openolt_read_sysinfo(const char* field_name, char* field_val)
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800493{
494 FILE *fp;
495 /* Prepare the command*/
496 char command[150];
497
498 snprintf(command, sizeof command, "bash -l -c \"onlpdump -s\" | perl -ne 'print $1 if /%s: (\\S+)/'", field_name);
499 /* Open the command for reading. */
500 fp = popen(command, "r");
501 if (fp == NULL) {
502 /*The client has to check for a Null field value in this case*/
Jason Huangb6843dc2019-07-22 17:46:06 +0800503 OPENOLT_LOG(INFO, openolt_log_id, "Failed to query the %s\n", field_name);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800504 return field_val;
505 }
506
507 /*Read the field value*/
508 if (fp) {
Jason Huangd33b4d82019-05-15 18:22:57 +0800509 uint8_t ret;
510 ret = fread(field_val, OPENOLT_FIELD_LEN, 1, fp);
511 if (ret >= OPENOLT_FIELD_LEN)
Jason Huangb6843dc2019-07-22 17:46:06 +0800512 OPENOLT_LOG(INFO, openolt_log_id, "Read data length %u\n", ret);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800513 pclose(fp);
514 }
515 return field_val;
516}
517
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400518Status GetDeviceInfo_(openolt::DeviceInfo* device_info) {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500519 device_info->set_vendor(VENDOR_ID);
520 device_info->set_model(MODEL_ID);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400521 device_info->set_hardware_version("");
522 device_info->set_firmware_version(firmware_version);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500523 device_info->set_technology(board_technology);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500524 device_info->set_pon_ports(num_of_pon_ports);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500525
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800526 char serial_number[OPENOLT_FIELD_LEN];
527 memset(serial_number, '\0', OPENOLT_FIELD_LEN);
528 openolt_read_sysinfo("Serial Number", serial_number);
Jason Huangb6843dc2019-07-22 17:46:06 +0800529 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device serial number %s\n", serial_number);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800530 device_info->set_device_serial_number(serial_number);
531
Craig Lutgenb2601f02018-10-23 13:04:31 -0500532 // Legacy, device-wide ranges. To be deprecated when adapter
533 // is upgraded to support per-interface ranges
Jason Huangb1fad572019-05-28 19:02:30 +0800534 if (board_technology == "XGS-PON") {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500535 device_info->set_onu_id_start(1);
536 device_info->set_onu_id_end(255);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600537 device_info->set_alloc_id_start(MIN_ALLOC_ID_XGSPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500538 device_info->set_alloc_id_end(16383);
539 device_info->set_gemport_id_start(1024);
540 device_info->set_gemport_id_end(65535);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500541 device_info->set_flow_id_start(1);
542 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500543 }
Jason Huangd33b4d82019-05-15 18:22:57 +0800544 else if (board_technology == "GPON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500545 device_info->set_onu_id_start(1);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500546 device_info->set_onu_id_end(127);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600547 device_info->set_alloc_id_start(MIN_ALLOC_ID_GPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500548 device_info->set_alloc_id_end(767);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500549 device_info->set_gemport_id_start(256);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500550 device_info->set_gemport_id_end(4095);
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 }
Craig Lutgenb2601f02018-10-23 13:04:31 -0500554
555 std::map<std::string, openolt::DeviceInfo::DeviceResourceRanges*> ranges;
556 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
557 std::string intf_technology = intf_technologies[intf_id];
558 openolt::DeviceInfo::DeviceResourceRanges *range = ranges[intf_technology];
559 if(range == nullptr) {
560 range = device_info->add_ranges();
561 ranges[intf_technology] = range;
562 range->set_technology(intf_technology);
563
Jason Huangb6843dc2019-07-22 17:46:06 +0800564 if (intf_technology == "XGS-PON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500565 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
566
567 pool = range->add_pools();
568 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
569 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
570 pool->set_start(1);
571 pool->set_end(255);
572
573 pool = range->add_pools();
574 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
575 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_SAME_TECH);
576 pool->set_start(1024);
577 pool->set_end(16383);
578
579 pool = range->add_pools();
580 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
581 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
582 pool->set_start(1024);
583 pool->set_end(65535);
584
585 pool = range->add_pools();
586 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
587 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
588 pool->set_start(1);
589 pool->set_end(16383);
590 }
Jason Huangb6843dc2019-07-22 17:46:06 +0800591 else if (intf_technology == "GPON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500592 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
593
594 pool = range->add_pools();
595 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
596 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
597 pool->set_start(1);
598 pool->set_end(127);
599
600 pool = range->add_pools();
601 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
602 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_SAME_TECH);
603 pool->set_start(256);
604 pool->set_end(757);
605
606 pool = range->add_pools();
607 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
608 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
609 pool->set_start(256);
610 pool->set_end(4095);
611
612 pool = range->add_pools();
613 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
614 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
615 pool->set_start(1);
616 pool->set_end(16383);
617 }
618 }
619
620 range->add_intf_ids(intf_id);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500621 }
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400622
623 // FIXME: Once dependency problem is fixed
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500624 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400625 // device_info->set_onu_id_end(XGPON_NUM_OF_ONUS - 1);
626 // device_info->set_alloc_id_start(1024);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500627 // device_info->set_alloc_id_end(XGPON_NUM_OF_ALLOC_IDS * num_of_pon_ports ? - 1);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400628 // device_info->set_gemport_id_start(XGPON_MIN_BASE_SERVICE_PORT_ID);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500629 // device_info->set_gemport_id_end(XGPON_NUM_OF_GEM_PORT_IDS_PER_PON * num_of_pon_ports ? - 1);
630 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400631
632 return Status::OK;
633}
634
Jason Huang88795222019-06-13 19:28:44 +0800635Status pushOltOperInd(uint32_t intf_id, const char *type, const char *state)
636{
Jason Huangb6843dc2019-07-22 17:46:06 +0800637 openolt::Indication ind;
638 openolt::IntfOperIndication* intf_oper_ind = new openolt::IntfOperIndication;
Jason Huang88795222019-06-13 19:28:44 +0800639
Jason Huangb6843dc2019-07-22 17:46:06 +0800640 intf_oper_ind->set_type(type);
641 intf_oper_ind->set_intf_id(intf_id);
642 intf_oper_ind->set_oper_state(state);
643 ind.set_allocated_intf_oper_ind(intf_oper_ind);
644 oltIndQ.push(ind);
Jason Huang88795222019-06-13 19:28:44 +0800645 return Status::OK;
646}
647
Jason Huangd33b4d82019-05-15 18:22:57 +0800648#define CLI_HOST_PROMPT_FORMAT "BCM.%u> "
649
650/* Build CLI prompt */
651static void openolt_cli_get_prompt_cb(bcmcli_session *session, char *buf, uint32_t max_len)
652{
653 snprintf(buf, max_len, CLI_HOST_PROMPT_FORMAT, dev_id);
654}
655
656static int _bal_apiend_cli_thread_handler(long data)
657{
658 char init_string[]="\n";
659 bcmcli_session *sess = current_session;
660 bcmos_task_parm bal_cli_task_p_dummy;
Jason Huangb6843dc2019-07-22 17:46:06 +0800661
Jason Huangd33b4d82019-05-15 18:22:57 +0800662 /* Switch to interactive mode if not stopped in the init script */
663 if (!bcmcli_is_stopped(sess))
664 {
665 /* Force a CLI command prompt
666 * The string passed into the parse function
667 * must be modifiable, so a string constant like
668 * bcmcli_parse(current_session, "\n") will not
669 * work.
670 */
671 bcmcli_parse(sess, init_string);
Jason Huangb6843dc2019-07-22 17:46:06 +0800672
Jason Huangd33b4d82019-05-15 18:22:57 +0800673 /* Process user input until EOF or quit command */
674 bcmcli_driver(sess);
675 };
Jason Huangb6843dc2019-07-22 17:46:06 +0800676 OPENOLT_LOG(INFO, openolt_log_id, "BAL API End CLI terminated\n");
Jason Huangd33b4d82019-05-15 18:22:57 +0800677
678 /* Cleanup */
679 bcmcli_session_close(current_session);
Jason Huangb6843dc2019-07-22 17:46:06 +0800680 bcmcli_token_destroy(NULL);
Jason Huangd33b4d82019-05-15 18:22:57 +0800681 return 0;
682}
683
684/* Init API CLI commands for the current device */
685bcmos_errno bcm_openolt_api_cli_init(bcmcli_entry *parent_dir, bcmcli_session *session)
686{
687 bcmos_errno rc;
688
689 api_parent_dir = parent_dir;
690
691 rc = bcm_api_cli_set_commands(session);
692
693#ifdef BCM_SUBSYSTEM_HOST
694 /* Subscribe for device change indication */
695 rc = rc ? rc : bcmolt_olt_sel_ind_register(_api_cli_olt_change_ind);
696#endif
697
698 return rc;
699}
700
701static bcmos_errno bcm_cli_quit(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
702{
703 bcmcli_stop(session);
704 bcmcli_session_print(session, "CLI terminated by 'Quit' command\n");
705 status_bcm_cli_quit = BCMOS_TRUE;
706
707 return BCM_ERR_OK;
708}
709
710int get_status_bcm_cli_quit(void) {
711 return status_bcm_cli_quit;
712}
713
714bcmos_errno bcmolt_apiend_cli_init() {
715 bcmos_errno ret;
716 bcmos_task_parm bal_cli_task_p = {};
717 bcmos_task_parm bal_cli_task_p_dummy;
718
719 /** before creating the task, check if it is already created by the other half of BAL i.e. Core side */
720 if (BCM_ERR_OK != bcmos_task_query(&bal_cli_thread, &bal_cli_task_p_dummy))
721 {
722 /* Create BAL CLI thread */
723 bal_cli_task_p.name = bal_cli_thread_name;
724 bal_cli_task_p.handler = _bal_apiend_cli_thread_handler;
725 bal_cli_task_p.priority = TASK_PRIORITY_CLI;
Jason Huangb6843dc2019-07-22 17:46:06 +0800726
Jason Huangd33b4d82019-05-15 18:22:57 +0800727 ret = bcmos_task_create(&bal_cli_thread, &bal_cli_task_p);
728 if (BCM_ERR_OK != ret)
729 {
730 bcmos_printf("Couldn't create BAL API end CLI thread\n");
731 return ret;
732 }
733 }
734}
735
Shad Ansari627b5782018-08-13 22:49:32 +0000736Status Enable_(int argc, char *argv[]) {
Jason Huangd33b4d82019-05-15 18:22:57 +0800737 bcmos_errno err;
738 bcmolt_host_init_parms init_parms = {};
739 init_parms.transport.type = BCM_HOST_API_CONN_LOCAL;
740 bcmcli_session_parm mon_session_parm;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000741
Shad Ansariedef2132018-08-10 22:14:50 +0000742 if (!state.is_activated()) {
Shad Ansari627b5782018-08-13 22:49:32 +0000743
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500744 vendor_init();
Jason Huangd33b4d82019-05-15 18:22:57 +0800745 /* Initialize host subsystem */
746 err = bcmolt_host_init(&init_parms);
747 if (BCM_ERR_OK != err) {
Jason Huangb6843dc2019-07-22 17:46:06 +0800748 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to init OLT\n");
Jason Huangd33b4d82019-05-15 18:22:57 +0800749 return bcm_to_grpc_err(err, "Failed to init OLT");
750 }
Craig Lutgen967a1d02018-11-27 10:41:51 -0600751
Jason Huangd33b4d82019-05-15 18:22:57 +0800752 /* Create CLI session */
753 memset(&mon_session_parm, 0, sizeof(mon_session_parm));
754 mon_session_parm.get_prompt = openolt_cli_get_prompt_cb;
755 mon_session_parm.access_right = BCMCLI_ACCESS_ADMIN;
756 bcmos_errno rc = bcmcli_session_open(&mon_session_parm, &current_session);
757 BUG_ON(rc != BCM_ERR_OK);
758
759 /* API CLI */
760 bcm_openolt_api_cli_init(NULL, current_session);
761
762 /* Add quit command */
763 BCMCLI_MAKE_CMD_NOPARM(NULL, "quit", "Quit", bcm_cli_quit);
764
765 err = bcmolt_apiend_cli_init();
766 if (BCM_ERR_OK != err) {
Jason Huangb6843dc2019-07-22 17:46:06 +0800767 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to add apiend init\n");
Jason Huangd33b4d82019-05-15 18:22:57 +0800768 return bcm_to_grpc_err(err, "Failed to add apiend init");
769 }
770
771 bcmos_fastlock_init(&data_lock, 0);
Jason Huangb6843dc2019-07-22 17:46:06 +0800772 OPENOLT_LOG(INFO, openolt_log_id, "Enable OLT - %s-%s\n", VENDOR_ID, MODEL_ID);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500773
Jason Huangd33b4d82019-05-15 18:22:57 +0800774 if (bcmolt_api_conn_mgr_is_connected(dev_id))
775 {
776 Status status = SubscribeIndication();
777 if (!status.ok()) {
Jason Huangb6843dc2019-07-22 17:46:06 +0800778 OPENOLT_LOG(ERROR, openolt_log_id, "SubscribeIndication failed - %s : %s\n",
Jason Huangd33b4d82019-05-15 18:22:57 +0800779 grpc_status_code_to_string(status.error_code()).c_str(),
780 status.error_message().c_str());
Jason Huangd33b4d82019-05-15 18:22:57 +0800781 return status;
782 }
783 bcmos_errno err;
784 bcmolt_odid dev;
Jason Huangb6843dc2019-07-22 17:46:06 +0800785 OPENOLT_LOG(INFO, openolt_log_id, "Enabling PON %d Devices ... \n", BCM_MAX_DEVS_PER_LINE_CARD);
Jason Huangd33b4d82019-05-15 18:22:57 +0800786 for (dev = 0; dev < BCM_MAX_DEVS_PER_LINE_CARD; dev++) {
787 bcmolt_device_cfg dev_cfg = { };
788 bcmolt_device_key dev_key = { };
789 dev_key.device_id = dev;
790 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
791 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
792 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
793 if (err == BCM_ERR_NOT_CONNECTED) {
794 bcmolt_device_key key = {.device_id = dev};
795 bcmolt_device_connect oper;
Jason Huangd33b4d82019-05-15 18:22:57 +0800796 BCMOLT_OPER_INIT(&oper, device, connect, key);
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +0800797 if (MODEL_ID == "asfvolt16") {
798 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
799 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_XGS__2_X);
800 } else if (MODEL_ID == "asgvolt64") {
801 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
802 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
803 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
804 }
Jason Huangd33b4d82019-05-15 18:22:57 +0800805 err = bcmolt_oper_submit(dev_id, &oper.hdr);
806 if (err)
Jason Huangb6843dc2019-07-22 17:46:06 +0800807 OPENOLT_LOG(ERROR, openolt_log_id, "Enable PON deivce %d failed\n", dev);
Jason Huangd33b4d82019-05-15 18:22:57 +0800808 bcmos_usleep(200000);
809 }
Jason Huangb1fad572019-05-28 19:02:30 +0800810 else {
Jason Huangb6843dc2019-07-22 17:46:06 +0800811 OPENOLT_LOG(WARNING, openolt_log_id, "PON deivce %d already connected\n", dev);
Jason Huangb1fad572019-05-28 19:02:30 +0800812 state.activate();
813 }
Jason Huangd33b4d82019-05-15 18:22:57 +0800814 }
815 init_stats();
Shad Ansari627b5782018-08-13 22:49:32 +0000816 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000817 }
Shad Ansariedef2132018-08-10 22:14:50 +0000818
Jason Huangd33b4d82019-05-15 18:22:57 +0800819 /* Start CLI */
Jason Huangb6843dc2019-07-22 17:46:06 +0800820 OPENOLT_LOG(INFO, def_log_id, "Starting CLI\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400821 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000822 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400823}
824
825Status Disable_() {
826 // bcmbal_access_terminal_cfg acc_term_obj;
827 // bcmbal_access_terminal_key key = { };
828 //
829 // if (state::is_activated) {
830 // std::cout << "Disable OLT" << std::endl;
831 // key.access_term_id = DEFAULT_ATERM_ID;
832 // BCMBAL_CFG_INIT(&acc_term_obj, access_terminal, key);
833 // BCMBAL_CFG_PROP_SET(&acc_term_obj, access_terminal, admin_state, BCMBAL_STATE_DOWN);
834 // bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(acc_term_obj.hdr));
835 // if (err) {
836 // std::cout << "ERROR: Failed to disable OLT" << std::endl;
837 // return bcm_to_grpc_err(err, "Failed to disable OLT");
838 // }
839 // }
840 // //If already disabled, generate an extra indication ????
841 // return Status::OK;
842 //This fails with Operation Not Supported, bug ???
843
844 //TEMPORARY WORK AROUND
Jason Huangb6843dc2019-07-22 17:46:06 +0800845 Status status = SetStateUplinkIf_(nni_intf_id, false);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400846 if (status.ok()) {
Shad Ansariedef2132018-08-10 22:14:50 +0000847 state.deactivate();
Jason Huangb6843dc2019-07-22 17:46:06 +0800848 OPENOLT_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
Jason Huang88795222019-06-13 19:28:44 +0800849 pushOltOperInd(nni_intf_id, "nni", "up");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400850 }
851 return status;
852
853}
854
855Status Reenable_() {
Jason Huangb6843dc2019-07-22 17:46:06 +0800856 Status status = SetStateUplinkIf_(0, true);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400857 if (status.ok()) {
Shad Ansariedef2132018-08-10 22:14:50 +0000858 state.activate();
Jason Huangb6843dc2019-07-22 17:46:06 +0800859 OPENOLT_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
Jason Huang88795222019-06-13 19:28:44 +0800860 pushOltOperInd(0, "nni", "up");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400861 }
862 return status;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000863}
864
Jason Huangd33b4d82019-05-15 18:22:57 +0800865bcmos_errno get_pon_interface_status(bcmolt_interface pon_ni, bcmolt_interface_state *state) {
866 bcmos_errno err;
867 bcmolt_pon_interface_key pon_key;
868 bcmolt_pon_interface_cfg pon_cfg;
869 pon_key.pon_ni = pon_ni;
870
871 BCMOLT_CFG_INIT(&pon_cfg, pon_interface, pon_key);
872 BCMOLT_FIELD_SET_PRESENT(&pon_cfg.data, pon_interface_cfg_data, state);
873 BCMOLT_FIELD_SET_PRESENT(&pon_cfg.data, pon_interface_cfg_data, itu);
874 err = bcmolt_cfg_get(dev_id, &pon_cfg.hdr);
875 *state = pon_cfg.data.state;
876 return err;
877}
878
Jason Huangb6843dc2019-07-22 17:46:06 +0800879inline uint64_t get_flow_status(uint16_t flow_id, uint16_t flow_type, uint16_t data_id) {
Jason Huang439d24f2019-06-26 03:25:05 +0800880 bcmos_errno err;
881 bcmolt_flow_key flow_key;
882 bcmolt_flow_cfg flow_cfg;
883
884 flow_key.flow_id = flow_id;
Jason Huangb6843dc2019-07-22 17:46:06 +0800885 flow_key.flow_type = (bcmolt_flow_type)flow_type;
Jason Huang439d24f2019-06-26 03:25:05 +0800886
887 BCMOLT_CFG_INIT(&flow_cfg, flow, flow_key);
888
889 switch (data_id) {
Jason Huangb6843dc2019-07-22 17:46:06 +0800890 case ONU_ID: //onu_id
891 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, onu_id);
Jason Huang439d24f2019-06-26 03:25:05 +0800892 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
893 if (err) {
Jason Huangb6843dc2019-07-22 17:46:06 +0800894 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get onu_id\n");
Jason Huang439d24f2019-06-26 03:25:05 +0800895 return err;
896 }
Jason Huangb6843dc2019-07-22 17:46:06 +0800897 return flow_cfg.data.onu_id;
898 case FLOW_TYPE:
Jason Huang439d24f2019-06-26 03:25:05 +0800899 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
900 if (err) {
Jason Huangb6843dc2019-07-22 17:46:06 +0800901 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get flow_type\n");
Jason Huang439d24f2019-06-26 03:25:05 +0800902 return err;
903 }
Jason Huangb6843dc2019-07-22 17:46:06 +0800904 return flow_cfg.key.flow_type;
Jason Huang439d24f2019-06-26 03:25:05 +0800905 case SVC_PORT_ID: //svc_port_id
906 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, svc_port_id);
907 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
908 if (err) {
Jason Huangb6843dc2019-07-22 17:46:06 +0800909 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get svc_port_id\n");
Jason Huang439d24f2019-06-26 03:25:05 +0800910 return err;
911 }
912 return flow_cfg.data.svc_port_id;
Jason Huangb6843dc2019-07-22 17:46:06 +0800913 case PRIORITY:
914 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, priority);
915 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
916 if (err) {
917 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get priority\n");
918 return err;
919 }
920 return flow_cfg.data.priority;
Jason Huang439d24f2019-06-26 03:25:05 +0800921 case COOKIE: //cookie
922 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, cookie);
923 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
924 if (err) {
Jason Huangb6843dc2019-07-22 17:46:06 +0800925 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get cookie\n");
Jason Huang439d24f2019-06-26 03:25:05 +0800926 return err;
927 }
928 return flow_cfg.data.cookie;
Jason Huangb6843dc2019-07-22 17:46:06 +0800929 case INGRESS_INTF_TYPE: //ingress intf_type
930 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
931 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
932 if (err) {
933 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get ingress intf_type\n");
934 return err;
935 }
936 return flow_cfg.data.ingress_intf.intf_type;
937 case EGRESS_INTF_TYPE: //egress intf_type
938 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
939 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
940 if (err) {
941 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress intf_type\n");
942 return err;
943 }
944 return flow_cfg.data.egress_intf.intf_type;
945 case INGRESS_INTF_ID: //ingress intf_id
946 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
947 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
948 if (err) {
949 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get ingress intf_id\n");
950 return err;
951 }
952 return flow_cfg.data.ingress_intf.intf_id;
953 case EGRESS_INTF_ID: //egress intf_id
954 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
955 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
956 if (err) {
957 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress intf_id\n");
958 return err;
959 }
960 return flow_cfg.data.egress_intf.intf_id;
961 case CLASSIFIER_O_VID:
962 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
963 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
964 if (err) {
965 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier o_vid\n");
966 return err;
967 }
968 return flow_cfg.data.classifier.o_vid;
969 case CLASSIFIER_O_PBITS:
970 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
971 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
972 if (err) {
973 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier o_pbits\n");
974 return err;
975 }
976 return flow_cfg.data.classifier.o_pbits;
977 case CLASSIFIER_I_VID:
978 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
979 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
980 if (err) {
981 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier i_vid\n");
982 return err;
983 }
984 return flow_cfg.data.classifier.i_vid;
985 case CLASSIFIER_I_PBITS:
986 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
987 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
988 if (err) {
989 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier i_pbits\n");
990 return err;
991 }
992 return flow_cfg.data.classifier.i_pbits;
993 case CLASSIFIER_ETHER_TYPE:
994 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
995 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
996 if (err) {
997 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier ether_type\n");
998 return err;
999 }
1000 return flow_cfg.data.classifier.ether_type;
1001 case CLASSIFIER_IP_PROTO:
1002 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1003 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1004 if (err) {
1005 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier ip_proto\n");
1006 return err;
1007 }
1008 return flow_cfg.data.classifier.ip_proto;
1009 case CLASSIFIER_SRC_PORT:
1010 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1011 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1012 if (err) {
1013 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier src_port\n");
1014 return err;
1015 }
1016 return flow_cfg.data.classifier.src_port;
1017 case CLASSIFIER_DST_PORT:
1018 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1019 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1020 if (err) {
1021 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier dst_port\n");
1022 return err;
1023 }
1024 return flow_cfg.data.classifier.dst_port;
1025 case CLASSIFIER_PKT_TAG_TYPE:
1026 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1027 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1028 if (err) {
1029 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier pkt_tag_type\n");
1030 return err;
1031 }
1032 return flow_cfg.data.classifier.pkt_tag_type;
1033 case EGRESS_QOS_TYPE:
1034 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
1035 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1036 if (err) {
1037 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos type\n");
1038 return err;
1039 }
1040 return flow_cfg.data.egress_qos.type;
1041 case EGRESS_QOS_QUEUE_ID:
1042 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
1043 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1044 if (err) {
1045 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos queue_id\n");
1046 return err;
1047 }
1048 switch (flow_cfg.data.egress_qos.type) {
1049 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE:
1050 return flow_cfg.data.egress_qos.u.fixed_queue.queue_id;
1051 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE:
1052 return flow_cfg.data.egress_qos.u.tc_to_queue.tc_to_queue_id;
1053 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC:
1054 return flow_cfg.data.egress_qos.u.pbit_to_tc.tc_to_queue_id;
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08001055 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE:
1056 return flow_cfg.data.egress_qos.u.priority_to_queue.tm_q_set_id;
Jason Huangb6843dc2019-07-22 17:46:06 +08001057 case BCMOLT_EGRESS_QOS_TYPE_NONE:
1058 default:
1059 return -1;
1060 }
1061 case EGRESS_QOS_TM_SCHED_ID:
1062 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
1063 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1064 if (err) {
1065 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos tm_sched_id\n");
1066 return err;
1067 }
1068 return flow_cfg.data.egress_qos.tm_sched.id;
1069 case ACTION_CMDS_BITMASK:
1070 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1071 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1072 if (err) {
1073 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action cmds_bitmask\n");
1074 return err;
1075 }
1076 return flow_cfg.data.action.cmds_bitmask;
1077 case ACTION_O_VID:
1078 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1079 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1080 if (err) {
1081 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action o_vid\n");
1082 return err;
1083 }
1084 return flow_cfg.data.action.o_vid;
1085 case ACTION_O_PBITS:
1086 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1087 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1088 if (err) {
1089 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action o_pbits\n");
1090 return err;
1091 }
1092 return flow_cfg.data.action.o_pbits;
1093 case ACTION_I_VID:
1094 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1095 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1096 if (err) {
1097 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action i_vid\n");
1098 return err;
1099 }
1100 return flow_cfg.data.action.i_vid;
1101 case ACTION_I_PBITS:
1102 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1103 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1104 if (err) {
1105 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action i_pbits\n");
1106 return err;
1107 }
1108 return flow_cfg.data.action.i_pbits;
1109 case STATE:
1110 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, state);
1111 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1112 if (err) {
1113 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get state\n");
1114 return err;
1115 }
1116 return flow_cfg.data.state;
Jason Huang439d24f2019-06-26 03:25:05 +08001117 default:
1118 return BCM_ERR_INTERNAL;
1119 }
1120
Jason Huangb6843dc2019-07-22 17:46:06 +08001121 return err;
Jason Huang439d24f2019-06-26 03:25:05 +08001122}
1123
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001124Status EnablePonIf_(uint32_t intf_id) {
Jason Huangd33b4d82019-05-15 18:22:57 +08001125 bcmos_errno err = BCM_ERR_OK;
Jason Huangb1fad572019-05-28 19:02:30 +08001126 bcmolt_pon_interface_cfg interface_obj;
Jason Huangd33b4d82019-05-15 18:22:57 +08001127 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1128 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
1129 bcmolt_interface_state state;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001130
Jason Huangd33b4d82019-05-15 18:22:57 +08001131 err = get_pon_interface_status((bcmolt_interface)intf_id, &state);
1132 if (err == BCM_ERR_OK) {
1133 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001134 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
Jason Huangd33b4d82019-05-15 18:22:57 +08001135 return Status::OK;
1136 }
1137 }
Jason Huangb1fad572019-05-28 19:02:30 +08001138 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
Jason Huangd33b4d82019-05-15 18:22:57 +08001139 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
Jason Huangb1fad572019-05-28 19:02:30 +08001140 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
1141 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.interval, 5000);
1142 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.onu_post_discovery_mode,
1143 BCMOLT_ONU_POST_DISCOVERY_MODE_ACTIVATE);
Jason Huangb6843dc2019-07-22 17:46:06 +08001144 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.los, true);
1145 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.onu_alarms, true);
1146 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.tiwi, true);
1147 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.ack_timeout, true);
1148 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.sfi, true);
1149 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.loki, true);
Jason Huangd33b4d82019-05-15 18:22:57 +08001150 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1151 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
Jason Huangb1fad572019-05-28 19:02:30 +08001152
1153 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1154 if (err != BCM_ERR_OK) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001155 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to enable discovery onu, PON interface %d, err %d\n", intf_id, err);
Jason Huangb1fad572019-05-28 19:02:30 +08001156 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
1157 }
Jason Huangd33b4d82019-05-15 18:22:57 +08001158 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1159 if (err != BCM_ERR_OK) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001160 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", intf_id);
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001161 return bcm_to_grpc_err(err, "Failed to enable PON interface");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001162 }
Thiyagarajan Subramani0695c982019-06-05 07:30:50 -07001163 else {
Jason Huangb6843dc2019-07-22 17:46:06 +08001164 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
1165 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08001166 CreateDefaultSched(intf_id, downstream);
1167 CreateDefaultQueue(intf_id, downstream);
Thiyagarajan Subramani0695c982019-06-05 07:30:50 -07001168 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001169
1170 return Status::OK;
1171}
1172
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001173Status ProbeDeviceCapabilities_() {
Jason Huangd33b4d82019-05-15 18:22:57 +08001174 bcmos_errno err;
1175 bcmolt_device_cfg dev_cfg = { };
1176 bcmolt_device_key dev_key = { };
1177 bcmolt_olt_cfg olt_cfg = { };
1178 bcmolt_olt_key olt_key = { };
Jason Huangd33b4d82019-05-15 18:22:57 +08001179 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
1180 bcmolt_topology topo = { };
Jason Huangb6843dc2019-07-22 17:46:06 +08001181
Jason Huangd33b4d82019-05-15 18:22:57 +08001182 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
1183 topo.topology_maps.arr = &topo_map[0];
1184 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
1185 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
1186 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
1187 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
1188 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
1189 err = bcmolt_cfg_get(dev_id, &olt_cfg.hdr);
1190 if (err) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001191 OPENOLT_LOG(ERROR, openolt_log_id, "cfg: Failed to query OLT\n");
Jason Huangd33b4d82019-05-15 18:22:57 +08001192 return bcm_to_grpc_err(err, "cfg: Failed to query OLT");
1193 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001194
Jason Huangd33b4d82019-05-15 18:22:57 +08001195 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
1196 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
1197
Jason Huangb6843dc2019-07-22 17:46:06 +08001198 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
Jason Huangd33b4d82019-05-15 18:22:57 +08001199 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
1200 ? "up" : "down");
1201
Jason Huangb6843dc2019-07-22 17:46:06 +08001202 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
Jason Huangd33b4d82019-05-15 18:22:57 +08001203 num_of_nni_ports,
1204 num_of_pon_ports,
Jason Huangb6843dc2019-07-22 17:46:06 +08001205 BCM_MAX_DEVS_PER_LINE_CARD);
Jason Huangd33b4d82019-05-15 18:22:57 +08001206
Jason Huangb6843dc2019-07-22 17:46:06 +08001207 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
1208 dev_key.device_id = devid;
1209 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
1210 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
1211 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
1212 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
1213 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
1214 if (err) {
1215 OPENOLT_LOG(ERROR, openolt_log_id, "device: Failed to query OLT\n");
1216 return bcm_to_grpc_err(err, "device: Failed to query OLT");
1217 }
1218
1219 std::string bal_version;
1220 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
1221 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
1222 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
1223 firmware_version = "BAL." + bal_version + "__" + firmware_version;
1224
1225 switch(dev_cfg.data.system_mode) {
1226 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
1227 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
1228 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
1229 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
1230 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
1231 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
1232 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
1233 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
1234 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
1235 case 20: board_technology = MIXED_TECH; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,MIXED_TECH); break;
1236 }
1237
1238 switch(dev_cfg.data.chip_family) {
1239 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X_: chip_family = "Maple"; break;
1240 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X_: chip_family = "Aspen"; break;
1241 }
1242
1243 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s object model: %d, family: %s, board_technology: %s\n",
1244 devid, BCM_MAX_PONS_PER_DEV, bal_version.c_str(), BAL_API_VERSION, chip_family.c_str(), board_technology.c_str());
1245
1246 bcmos_usleep(500000);
1247 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001248
1249 return Status::OK;
1250}
Jason Huangb6843dc2019-07-22 17:46:06 +08001251#if 0
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001252Status ProbePonIfTechnology_() {
1253 // Probe maximum extent possible as configured into BAL driver to determine
1254 // which are active in the current BAL topology. And for those
1255 // that are active, determine each port's access technology, i.e. "gpon" or "xgspon".
1256 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
Jason Huangd33b4d82019-05-15 18:22:57 +08001257 bcmolt_pon_interface_cfg interface_obj;
1258 bcmolt_pon_interface_key interface_key;
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001259
Jason Huangd33b4d82019-05-15 18:22:57 +08001260 interface_key.pon_ni = intf_id;
1261 BCMOLT_CFG_INIT(&interface_obj, pon_interface, interface_key);
Jason Huangb6843dc2019-07-22 17:46:06 +08001262 if (board_technology == "XGS-PON")
1263 BCMOLT_MSG_FIELD_GET(&interface_obj, xgs_ngpon2_trx);
1264 else if (board_technology == "GPON")
1265 BCMOLT_MSG_FIELD_GET(&interface_obj, gpon_trx);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001266
Jason Huangd33b4d82019-05-15 18:22:57 +08001267 bcmos_errno err = bcmolt_cfg_get(dev_id, &interface_obj.hdr);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001268 if (err != BCM_ERR_OK) {
Craig Lutgenb2601f02018-10-23 13:04:31 -05001269 intf_technologies[intf_id] = UNKNOWN_TECH;
Jason Huangb6843dc2019-07-22 17:46:06 +08001270 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 -05001271 }
1272 else {
Jason Huangb1fad572019-05-28 19:02:30 +08001273 if (board_technology == "XGS-PON") {
Jason Huangd33b4d82019-05-15 18:22:57 +08001274 switch(interface_obj.data.xgpon_trx.transceiver_type) {
1275 case BCMOLT_XGPON_TRX_TYPE_LTH_7222_PC:
1276 case BCMOLT_XGPON_TRX_TYPE_WTD_RTXM266_702:
1277 case BCMOLT_XGPON_TRX_TYPE_LTH_7222_BC_PLUS:
1278 case BCMOLT_XGPON_TRX_TYPE_LTH_7226_PC:
1279 case BCMOLT_XGPON_TRX_TYPE_LTH_5302_PC:
1280 case BCMOLT_XGPON_TRX_TYPE_LTH_7226_A_PC_PLUS:
1281 case BCMOLT_XGPON_TRX_TYPE_D272RR_SSCB_DM:
Jason Huangb1fad572019-05-28 19:02:30 +08001282 intf_technologies[intf_id] = "XGS-PON";
Jason Huangd33b4d82019-05-15 18:22:57 +08001283 break;
1284 }
1285 } else if (board_technology == "GPON") {
1286 switch(interface_obj.data.gpon_trx.transceiver_type) {
1287 case BCMOLT_TRX_TYPE_SPS_43_48_H_HP_CDE_SD_2013:
1288 case BCMOLT_TRX_TYPE_LTE_3680_M:
1289 case BCMOLT_TRX_TYPE_SOURCE_PHOTONICS:
1290 case BCMOLT_TRX_TYPE_LTE_3680_P_TYPE_C_PLUS:
Jason Huangb6843dc2019-07-22 17:46:06 +08001291 case BCMOLT_TRX_TYPE_LTE_3680_P_BC:
Jason Huangd33b4d82019-05-15 18:22:57 +08001292 intf_technologies[intf_id] = "GPON";
1293 break;
1294 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001295 }
Craig Lutgenb2601f02018-10-23 13:04:31 -05001296
1297 if (board_technology != UNKNOWN_TECH) {
1298 board_technology = intf_technologies[intf_id];
1299 } else if (board_technology != MIXED_TECH && board_technology != intf_technologies[intf_id]) {
1300 intf_technologies[intf_id] = MIXED_TECH;
1301 }
1302
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001303 }
1304 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001305 return Status::OK;
1306}
Jason Huangb6843dc2019-07-22 17:46:06 +08001307#endif
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001308unsigned NumNniIf_() {return num_of_nni_ports;}
1309unsigned NumPonIf_() {return num_of_pon_ports;}
1310
Jason Huangd33b4d82019-05-15 18:22:57 +08001311bcmos_errno get_nni_interface_status(bcmolt_interface id, bcmolt_interface_state *state) {
1312 bcmos_errno err;
1313 bcmolt_nni_interface_key nni_key;
1314 bcmolt_nni_interface_cfg nni_cfg;
1315 nni_key.id = id;
1316
1317 BCMOLT_CFG_INIT(&nni_cfg, nni_interface, nni_key);
1318 BCMOLT_FIELD_SET_PRESENT(&nni_cfg.data, nni_interface_cfg_data, state);
1319 err = bcmolt_cfg_get(dev_id, &nni_cfg.hdr);
1320 *state = nni_cfg.data.state;
1321 return err;
1322}
1323
Jason Huangb6843dc2019-07-22 17:46:06 +08001324Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
Jason Huangd33b4d82019-05-15 18:22:57 +08001325 bcmos_errno err = BCM_ERR_OK;
1326 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
1327 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
1328 bcmolt_interface_state state;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001329
Jason Huangd33b4d82019-05-15 18:22:57 +08001330 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
1331 if (err == BCM_ERR_OK) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001332 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
1333 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
1334 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08001335 CreateDefaultSched(intf_id, upstream);
1336 CreateDefaultQueue(intf_id, upstream);
Jason Huangd33b4d82019-05-15 18:22:57 +08001337 return Status::OK;
Jason Huangb6843dc2019-07-22 17:46:06 +08001338 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1339 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
1340 return Status::OK;
Jason Huangd33b4d82019-05-15 18:22:57 +08001341 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001342 }
1343
Jason Huangd33b4d82019-05-15 18:22:57 +08001344 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
Jason Huangb6843dc2019-07-22 17:46:06 +08001345 if (set_state) {
1346 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1347 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1348 } else {
1349 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1350 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1351 }
Jason Huangd33b4d82019-05-15 18:22:57 +08001352 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
1353 if (err != BCM_ERR_OK) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001354 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err %d\n",
1355 (set_state)?"enable":"disable", intf_id, err);
Jason Huangd33b4d82019-05-15 18:22:57 +08001356 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001357 }
Thiyagarajan Subramani0695c982019-06-05 07:30:50 -07001358 else {
Jason Huangb6843dc2019-07-22 17:46:06 +08001359 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
1360 if (set_state) {
1361 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08001362 CreateDefaultSched(intf_id, upstream);
1363 CreateDefaultQueue(intf_id, upstream);
Jason Huangb6843dc2019-07-22 17:46:06 +08001364 }
Thiyagarajan Subramani0695c982019-06-05 07:30:50 -07001365 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001366
1367 return Status::OK;
1368}
1369
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001370Status DisablePonIf_(uint32_t intf_id) {
Jason Huangd33b4d82019-05-15 18:22:57 +08001371 bcmolt_pon_interface_cfg interface_obj;
1372 bcmolt_pon_interface_key interface_key;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001373
Jason Huangd33b4d82019-05-15 18:22:57 +08001374 interface_key.pon_ni = intf_id;
1375 BCMOLT_CFG_INIT(&interface_obj, pon_interface, interface_key);
1376 BCMOLT_MSG_FIELD_GET(&interface_obj, state);
1377 bcmos_errno err = bcmolt_cfg_get(dev_id, &interface_obj.hdr);
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001378 if (err) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001379 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", intf_id);
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001380 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001381 }
1382
1383 return Status::OK;
1384}
1385
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001386Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001387 const char *vendor_id, const char *vendor_specific, uint32_t pir) {
Jason Huangb1fad572019-05-28 19:02:30 +08001388 bcmos_errno err = BCM_ERR_OK;
1389 bcmolt_onu_cfg onu_cfg;
1390 bcmolt_onu_key onu_key;
Jason Huangd33b4d82019-05-15 18:22:57 +08001391 bcmolt_serial_number serial_number; /**< ONU serial number */
1392 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001393
Jason Huangb1fad572019-05-28 19:02:30 +08001394 onu_key.onu_id = onu_id;
1395 onu_key.pon_ni = intf_id;
1396 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1397 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1398 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
1399 if (err == BCM_ERR_OK) {
1400 if ((onu_cfg.data.onu_state == BCMOLT_ONU_STATE_PROCESSING ||
1401 onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) ||
1402 (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_INACTIVE &&
Jason Huangb6843dc2019-07-22 17:46:06 +08001403 onu_cfg.data.onu_old_state == BCMOLT_ONU_STATE_NOT_CONFIGURED))
Jason Huangb1fad572019-05-28 19:02:30 +08001404 return Status::OK;
1405 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001406
Jason Huangb6843dc2019-07-22 17:46:06 +08001407 OPENOLT_LOG(INFO, openolt_log_id, "Enabling ONU %d on PON %d : vendor id %s, \
1408vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Jason Huangb1fad572019-05-28 19:02:30 +08001409 vendor_specific_to_str(vendor_specific).c_str(), pir);
1410
Jason Huangd33b4d82019-05-15 18:22:57 +08001411 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1412 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
Jason Huangb1fad572019-05-28 19:02:30 +08001413 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
Jason Huangb1fad572019-05-28 19:02:30 +08001414 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1415 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1416 /*set burst and data profiles to fec disabled*/
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08001417 if (board_technology == "XGS-PON") {
1418 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1419 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1420 } else if (board_technology == "GPON") {
1421 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1422 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1423 }
Jason Huangb6843dc2019-07-22 17:46:06 +08001424 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
Jason Huangb1fad572019-05-28 19:02:30 +08001425 if (err != BCM_ERR_OK) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001426 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to set activate ONU %d on PON %d, err %d\n", onu_id, intf_id, err);
Jason Huangb1fad572019-05-28 19:02:30 +08001427 return bcm_to_grpc_err(err, "Failed to activate ONU");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001428 }
Jason Huangd33b4d82019-05-15 18:22:57 +08001429
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001430 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001431}
1432
Jonathan Davis70c21812018-07-19 15:32:10 -04001433Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1434 const char *vendor_id, const char *vendor_specific) {
Jason Huangb1fad572019-05-28 19:02:30 +08001435 bcmos_errno err = BCM_ERR_OK;
1436 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1437 bcmolt_onu_cfg onu_cfg;
1438 bcmolt_onu_key onu_key; /**< Object key. */
1439 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001440
Jason Huangb1fad572019-05-28 19:02:30 +08001441 onu_key.onu_id = onu_id;
1442 onu_key.pon_ni = intf_id;
1443 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1444 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1445 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
1446 if (err == BCM_ERR_OK) {
1447 switch (onu_state) {
1448 case BCMOLT_ONU_OPERATION_ACTIVE:
1449 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
1450 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
1451 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1452 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1453 if (err != BCM_ERR_OK) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001454 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to \
1455deactivate ONU %d on PON %d, err %d\n", onu_id, intf_id, err);
Jason Huangb1fad572019-05-28 19:02:30 +08001456 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1457 }
1458 break;
1459 }
Jonathan Davis70c21812018-07-19 15:32:10 -04001460 }
1461
1462 return Status::OK;
1463}
1464
1465Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001466 const char *vendor_id, const char *vendor_specific) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001467
Jason Huangb6843dc2019-07-22 17:46:06 +08001468 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 -05001469 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1470
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001471 // Need to deactivate before removing it (BAL rules)
1472
1473 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
1474 // Sleep to allow the state to propagate
1475 // We need the subscriber terminal object to be admin down before removal
1476 // Without sleep the race condition is lost by ~ 20 ms
1477 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1478
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001479 // TODO: Delete the schedulers and queues.
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001480
Jason Huangd33b4d82019-05-15 18:22:57 +08001481 bcmolt_onu_cfg cfg_obj;
1482 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001483
Jason Huangb6843dc2019-07-22 17:46:06 +08001484 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 -04001485 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001486
Jason Huangd33b4d82019-05-15 18:22:57 +08001487 key.onu_id = onu_id;
1488 key.pon_ni = intf_id;
1489 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001490
Jason Huangb6843dc2019-07-22 17:46:06 +08001491 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001492 if (err != BCM_ERR_OK)
1493 {
Jason Huangb6843dc2019-07-22 17:46:06 +08001494 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 -04001495 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001496 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1497 }
1498
Jason Huangd33b4d82019-05-15 18:22:57 +08001499 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001500}
1501
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001502#define MAX_CHAR_LENGTH 20
1503#define MAX_OMCI_MSG_LENGTH 44
1504Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Jason Huangd33b4d82019-05-15 18:22:57 +08001505 bcmolt_bin_str buf = {};
1506 bcmolt_onu_cpu_packets omci_cpu_packets;
1507 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001508
Jason Huangd33b4d82019-05-15 18:22:57 +08001509 key.pon_ni = intf_id;
1510 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001511
Jason Huangd33b4d82019-05-15 18:22:57 +08001512 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1513 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1514 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001515
1516 // ???
1517 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1518 buf.len = MAX_OMCI_MSG_LENGTH;
1519 } else {
1520 buf.len = pkt.size()/2;
1521 }
1522
1523 /* Send the OMCI packet using the BAL remote proxy API */
1524 uint16_t idx1 = 0;
1525 uint16_t idx2 = 0;
1526 uint8_t arraySend[buf.len];
1527 char str1[MAX_CHAR_LENGTH];
1528 char str2[MAX_CHAR_LENGTH];
1529 memset(&arraySend, 0, buf.len);
1530
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001531 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1532 sprintf(str1,"%c", pkt[idx1]);
1533 sprintf(str2,"%c", pkt[++idx1]);
1534 strcat(str1,str2);
1535 arraySend[idx2] = strtol(str1, NULL, 16);
1536 }
1537
Jason Huangd33b4d82019-05-15 18:22:57 +08001538 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1539 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001540
Jason Huangd33b4d82019-05-15 18:22:57 +08001541 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1542 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1543 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001544
Jason Huangd33b4d82019-05-15 18:22:57 +08001545 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001546 if (err) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001547 OPENOLT_LOG(ERROR, omci_log_id, "Error sending OMCI message to ONU %d on PON %d\n", onu_id, intf_id);
1548 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001549 } else {
Jason Huangb6843dc2019-07-22 17:46:06 +08001550 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 -05001551 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001552 }
Jason Huangd33b4d82019-05-15 18:22:57 +08001553 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001554
1555 return Status::OK;
1556}
1557
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001558Status OnuPacketOut_(uint32_t intf_id, uint32_t onu_id, uint32_t port_no, uint32_t gemport_id, const std::string pkt) {
Jason Huangd33b4d82019-05-15 18:22:57 +08001559 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1560 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1561 bcmolt_bin_str buf = {};
1562 bcmolt_gem_port_id gem_port_id_array[1];
1563 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001564
Craig Lutgen967a1d02018-11-27 10:41:51 -06001565 if (port_no > 0) {
1566 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001567 if (gemport_id == 0) {
1568 bcmos_fastlock_lock(&data_lock);
1569 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1570 // Pick any flow that is mapped with the same port_no.
1571 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1572 if (it != port_to_flows.end() && !it->second.empty()) {
1573 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1574 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1575 if (fit != flowid_to_gemport.end()) {
1576 found = true;
1577 gemport_id = fit->second;
1578 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001579 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001580 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001581
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001582 if (!found) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001583 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 -08001584 onu_id, port_no, intf_id);
1585 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1586 }
Jason Huangb6843dc2019-07-22 17:46:06 +08001587 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 -08001588 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001589 }
1590
Jason Huangd33b4d82019-05-15 18:22:57 +08001591 gem_port_id_array[0] = gemport_id;
1592 gem_port_list.len = 1;
1593 gem_port_list.arr = gem_port_id_array;
1594 buf.len = pkt.size();
1595 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1596 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1597
1598 /* init the API struct */
1599 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1600 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1601 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1602 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1603 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1604
Jason Huangb6843dc2019-07-22 17:46:06 +08001605 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
Jason Huangd33b4d82019-05-15 18:22:57 +08001606 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1607
1608 /* call API */
Jason Huangb6843dc2019-07-22 17:46:06 +08001609 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001610 }
1611 else {
Jason Huangd33b4d82019-05-15 18:22:57 +08001612 //TODO: Port No is 0, it is coming sender requirement.
Jason Huangb6843dc2019-07-22 17:46:06 +08001613 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
Jason Huangd33b4d82019-05-15 18:22:57 +08001614 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001615 }
Jason Huangd33b4d82019-05-15 18:22:57 +08001616 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001617
1618 return Status::OK;
1619}
1620
Jason Huangd33b4d82019-05-15 18:22:57 +08001621Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt, bcmolt_flow_id flow_id) {
Jason Huangd33b4d82019-05-15 18:22:57 +08001622 bcmolt_flow_key key = {}; /* declare key */
1623 bcmolt_bin_str buffer = {};
1624 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001625
Jason Huangb6843dc2019-07-22 17:46:06 +08001626 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1627 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1628 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1629 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1630 key.flow_id = flow_id;
1631 else {
1632 if (flow_id_counters != 0) {
1633 for (int flowid=0; flowid < flow_id_counters; flowid++) {
1634 int flow_index = flow_id_data[flowid][0];
1635 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1636 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1637 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1638 key.flow_id = flow_index;
1639 break;
1640 }
1641 }
1642 }
1643 else
1644 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1645 }
1646
Thiyagarajan Subramani0695c982019-06-05 07:30:50 -07001647 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001648
Jason Huangd33b4d82019-05-15 18:22:57 +08001649 /* Initialize the API struct. */
1650 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001651
Jason Huangd33b4d82019-05-15 18:22:57 +08001652 buffer.len = pkt.size();
1653 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1654 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1655 if (buffer.arr == NULL) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001656 OPENOLT_LOG(ERROR, openolt_log_id, "allocate pakcet buffer failed\n");
Jason Huangd33b4d82019-05-15 18:22:57 +08001657 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate pakcet buffer failed");
1658 }
1659 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001660
Jason Huangd33b4d82019-05-15 18:22:57 +08001661 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
Jason Huangb6843dc2019-07-22 17:46:06 +08001662 if (err) {
1663 OPENOLT_LOG(ERROR, openolt_log_id, "Error sending packets to port %d, flow_id %d, err %d\n", intf_id, key.flow_id, err);
1664 } else {
1665 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction (flow_id %d)\n", intf_id, key.flow_id);
1666 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001667
1668 return Status::OK;
1669}
1670
Jason Huangd33b4d82019-05-15 18:22:57 +08001671uint32_t GetPortNum_(uint32_t flow_id) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001672 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001673 uint32_t port_no = 0;
1674 std::map<uint32_t, uint32_t >::const_iterator it = flowid_to_port.find(flow_id);
1675 if (it != flowid_to_port.end()) {
1676 port_no = it->second;
1677 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001678 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001679 return port_no;
1680}
1681
Jason Huangb6843dc2019-07-22 17:46:06 +08001682#define FLOW_LOG(level,msg,err) \
1683 do { \
1684 OPENOLT_LOG(level, openolt_log_id, "--------> %s (flow_id %d) err: %d <--------\n", msg, key.flow_id, err); \
1685 OPENOLT_LOG(level, openolt_log_id, "intf_id %d, onu_id %d, uni_id %d, port_no %u, cookie %"PRIu64"\n", \
1686 access_intf_id, onu_id, uni_id, port_no, cookie); \
1687 OPENOLT_LOG(level, openolt_log_id, "flow_type %s, queue_id %d, sched_id %d\n", flow_type.c_str(), \
1688 cfg.data.egress_qos.u.fixed_queue.queue_id, cfg.data.egress_qos.tm_sched.id); \
1689 OPENOLT_LOG(level, openolt_log_id, "Ingress(intfd_type %s, intf_id %d), Egress(intf_type %s, intf_id %d)\n", \
1690 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type), cfg.data.ingress_intf.intf_id, \
1691 GET_FLOW_INTERFACE_TYPE(cfg.data.egress_intf.intf_type), cfg.data.egress_intf.intf_id); \
1692 OPENOLT_LOG(level, openolt_log_id, "classifier(o_vid %d, o_pbits %d, i_vid %d, i_pbits %d, ether type 0x%x)\n", \
1693 c_val.o_vid, c_val.o_pbits, c_val.i_vid, c_val.i_pbits, classifier.eth_type()); \
1694 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", \
1695 c_val.ip_proto, gemport_id, c_val.src_port, c_val.dst_port, GET_PKT_TAG_TYPE(c_val.pkt_tag_type)); \
1696 OPENOLT_LOG(level, openolt_log_id, "action(cmds_bitmask %s, o_vid %d, o_pbits %d, i_vid %d, i_pbits %d)\n\n", \
1697 get_flow_acton_command(a_val.cmds_bitmask), a_val.o_vid, a_val.o_pbits, a_val.i_vid, a_val.i_pbits); \
1698 } while(0)
1699
1700#define FLOW_PARAM_LOG() \
1701 do { \
1702 OPENOLT_LOG(INFO, openolt_log_id, "--------> flow comparison (now before) <--------\n"); \
1703 OPENOLT_LOG(INFO, openolt_log_id, "flow_id (%d %d)\n", \
1704 key.flow_id, flow_index); \
1705 OPENOLT_LOG(INFO, openolt_log_id, "onu_id (%d %lu)\n", \
1706 cfg.data.onu_id , get_flow_status(flow_index, flow_id_data[flowid][1], ONU_ID)); \
1707 OPENOLT_LOG(INFO, openolt_log_id, "type (%d %lu)\n", \
1708 key.flow_type, get_flow_status(flow_index, flow_id_data[flowid][1], FLOW_TYPE)); \
1709 OPENOLT_LOG(INFO, openolt_log_id, "svc_port_id (%d %lu)\n", \
1710 cfg.data.svc_port_id, get_flow_status(flow_index, flow_id_data[flowid][1], SVC_PORT_ID)); \
1711 OPENOLT_LOG(INFO, openolt_log_id, "priority (%d %lu)\n", \
1712 cfg.data.priority, get_flow_status(flow_index, flow_id_data[flowid][1], PRIORITY)); \
1713 OPENOLT_LOG(INFO, openolt_log_id, "cookie (%lu %lu)\n", \
1714 cfg.data.cookie, get_flow_status(flow_index, flow_id_data[flowid][1], COOKIE)); \
1715 OPENOLT_LOG(INFO, openolt_log_id, "ingress intf_type (%s %s)\n", \
1716 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type), \
1717 GET_FLOW_INTERFACE_TYPE(get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_TYPE))); \
1718 OPENOLT_LOG(INFO, openolt_log_id, "ingress intf id (%d %lu)\n", \
1719 cfg.data.ingress_intf.intf_id , get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_ID)); \
1720 OPENOLT_LOG(INFO, openolt_log_id, "egress intf_type (%d %lu)\n", \
1721 cfg.data.egress_intf.intf_type , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_TYPE)); \
1722 OPENOLT_LOG(INFO, openolt_log_id, "egress intf_id (%d %lu)\n", \
1723 cfg.data.egress_intf.intf_id , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_ID)); \
1724 OPENOLT_LOG(INFO, openolt_log_id, "classifier o_vid (%d %lu)\n", \
1725 c_val.o_vid , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_VID)); \
1726 OPENOLT_LOG(INFO, openolt_log_id, "classifier o_pbits (%d %lu)\n", \
1727 c_val.o_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_PBITS)); \
1728 OPENOLT_LOG(INFO, openolt_log_id, "classifier i_vid (%d %lu)\n", \
1729 c_val.i_vid , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_VID)); \
1730 OPENOLT_LOG(INFO, openolt_log_id, "classifier i_pbits (%d %lu)\n", \
1731 c_val.i_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_PBITS)); \
1732 OPENOLT_LOG(INFO, openolt_log_id, "classifier ether_type (0x%x 0x%lx)\n", \
1733 c_val.ether_type , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_ETHER_TYPE)); \
1734 OPENOLT_LOG(INFO, openolt_log_id, "classifier ip_proto (%d %lu)\n", \
1735 c_val.ip_proto , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_IP_PROTO)); \
1736 OPENOLT_LOG(INFO, openolt_log_id, "classifier src_port (%d %lu)\n", \
1737 c_val.src_port , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_SRC_PORT)); \
1738 OPENOLT_LOG(INFO, openolt_log_id, "classifier dst_port (%d %lu)\n", \
1739 c_val.dst_port , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_DST_PORT)); \
1740 OPENOLT_LOG(INFO, openolt_log_id, "classifier pkt_tag_type (%s %s)\n", \
1741 GET_PKT_TAG_TYPE(c_val.pkt_tag_type), \
1742 GET_PKT_TAG_TYPE(get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_PKT_TAG_TYPE))); \
1743 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos type (%d %lu)\n", \
1744 cfg.data.egress_qos.type , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TYPE)); \
1745 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos queue_id (%d %lu)\n", \
1746 cfg.data.egress_qos.u.fixed_queue.queue_id, \
1747 get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_QUEUE_ID)); \
1748 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos sched_id (%d %lu)\n", \
1749 cfg.data.egress_qos.tm_sched.id, \
1750 get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TM_SCHED_ID)); \
1751 OPENOLT_LOG(INFO, openolt_log_id, "classifier cmds_bitmask (%s %s)\n", \
1752 get_flow_acton_command(a_val.cmds_bitmask), \
1753 get_flow_acton_command(get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_CMDS_BITMASK))); \
1754 OPENOLT_LOG(INFO, openolt_log_id, "action o_vid (%d %lu)\n", \
1755 a_val.o_vid , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_VID)); \
1756 OPENOLT_LOG(INFO, openolt_log_id, "action i_vid (%d %lu)\n", \
1757 a_val.i_vid , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_VID)); \
1758 OPENOLT_LOG(INFO, openolt_log_id, "action o_pbits (%d %lu)\n", \
1759 a_val.o_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_PBITS)); \
1760 OPENOLT_LOG(INFO, openolt_log_id, "action i_pbits (%d %lu)\n\n", \
1761 a_val.i_pbits, get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_PBITS)); \
1762 } while(0)
1763
1764#define FLOW_CHECKER
1765//#define SHOW_FLOW_PARAM
1766
Craig Lutgen967a1d02018-11-27 10:41:51 -06001767Status 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 +00001768 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001769 int32_t alloc_id, int32_t network_intf_id,
1770 int32_t gemport_id, const ::openolt::Classifier& classifier,
Craig Lutgen967a1d02018-11-27 10:41:51 -06001771 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie) {
Jason Huangd33b4d82019-05-15 18:22:57 +08001772 bcmolt_flow_cfg cfg;
1773 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001774 int32_t o_vid = -1;
1775 bool single_tag = false;
1776 uint32_t ether_type = 0;
Jason Huangb6843dc2019-07-22 17:46:06 +08001777 bcmolt_classifier c_val = { };
1778 bcmolt_action a_val = { };
1779 bcmolt_tm_queue_ref tm_val = { };
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08001780 int tm_qmp_id, tm_q_set_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001781
1782 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001783 if (flow_type.compare(upstream) == 0 ) {
Jason Huangd33b4d82019-05-15 18:22:57 +08001784 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001785 } else if (flow_type.compare(downstream) == 0) {
Jason Huangd33b4d82019-05-15 18:22:57 +08001786 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001787 } else {
Jason Huangb6843dc2019-07-22 17:46:06 +08001788 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001789 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001790 }
1791
Jason Huangd33b4d82019-05-15 18:22:57 +08001792 BCMOLT_CFG_INIT(&cfg, flow, key);
1793 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001794
Jason Huangb6843dc2019-07-22 17:46:06 +08001795 if (access_intf_id >= 0 && network_intf_id >= 0) {
1796 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
Jason Huangd33b4d82019-05-15 18:22:57 +08001797 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1798 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
Jason Huangb6843dc2019-07-22 17:46:06 +08001799 if (classifier.eth_type() == EAP_ETHER_TYPE || //EAPOL packet
1800 (classifier.ip_proto() == 17 && classifier.src_port() == 68 && classifier.dst_port() == 67)) { //DHCP packet
1801 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_HOST);
1802 } else {
1803 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1804 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
1805 }
1806 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1807 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1808 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
Jason Huangd33b4d82019-05-15 18:22:57 +08001809 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1810 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
1811 }
Jason Huangb6843dc2019-07-22 17:46:06 +08001812 } else {
1813 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
1814 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
Shad Ansari39739bc2018-09-13 21:38:37 +00001815 }
Jason Huangb6843dc2019-07-22 17:46:06 +08001816
Shad Ansari39739bc2018-09-13 21:38:37 +00001817 if (onu_id >= 0) {
Jason Huangd33b4d82019-05-15 18:22:57 +08001818 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001819 }
1820 if (gemport_id >= 0) {
Jason Huangd33b4d82019-05-15 18:22:57 +08001821 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001822 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001823 if (gemport_id >= 0 && port_no != 0) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001824 bcmos_fastlock_lock(&data_lock);
Jason Huangd33b4d82019-05-15 18:22:57 +08001825 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06001826 port_to_flows[port_no].insert(key.flow_id);
1827 flowid_to_gemport[key.flow_id] = gemport_id;
1828 }
1829 else
1830 {
1831 flowid_to_port[key.flow_id] = port_no;
1832 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001833 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001834 }
Shad Ansari39739bc2018-09-13 21:38:37 +00001835 if (priority_value >= 0) {
Jason Huangd33b4d82019-05-15 18:22:57 +08001836 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
Shad Ansari39739bc2018-09-13 21:38:37 +00001837 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001838
1839 {
Jason Huangd33b4d82019-05-15 18:22:57 +08001840 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001841 if (classifier.o_tpid()) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001842 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_tpid 0x%04x\n", classifier.o_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05001843 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, o_tpid, classifier.o_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001844 }
Jason Huangd33b4d82019-05-15 18:22:57 +08001845 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001846 if (classifier.o_vid()) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001847 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
1848 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001849 }
Jason Huangd33b4d82019-05-15 18:22:57 +08001850 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001851 if (classifier.i_tpid()) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001852 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_tpid 0x%04x\n", classifier.i_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05001853 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, i_tpid, classifier.i_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001854 }
Jason Huangd33b4d82019-05-15 18:22:57 +08001855 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001856 if (classifier.i_vid()) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001857 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
1858 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001859 }
1860
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001861 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001862 ether_type = classifier.eth_type();
Jason Huangb6843dc2019-07-22 17:46:06 +08001863 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
1864 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001865 }
1866
1867 /*
1868 if (classifier.dst_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001869 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_mac, classifier.dst_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001870 }
1871
1872 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001873 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001874 }
1875 */
1876
1877 if (classifier.ip_proto()) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001878 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
1879 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001880 }
1881
1882 /*
1883 if (classifier.dst_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001884 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_ip, classifier.dst_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001885 }
1886
1887 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001888 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001889 }
1890 */
1891
1892 if (classifier.src_port()) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001893 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
1894 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001895 }
1896
1897 if (classifier.dst_port()) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001898 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
1899 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001900 }
1901
1902 if (!classifier.pkt_tag_type().empty()) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001903 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001904 if (classifier.pkt_tag_type().compare("untagged") == 0) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001905 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001906 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001907 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001908 single_tag = true;
1909
Jason Huangb6843dc2019-07-22 17:46:06 +08001910 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
1911 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001912 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001913 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001914
Jason Huangb6843dc2019-07-22 17:46:06 +08001915 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
1916 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001917 }
1918 }
Jason Huangb6843dc2019-07-22 17:46:06 +08001919 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001920 }
1921
Jason Huangb6843dc2019-07-22 17:46:06 +08001922 if (cfg.data.egress_intf.intf_type != BCMOLT_FLOW_INTERFACE_TYPE_HOST) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001923 const ::openolt::ActionCmd& cmd = action.cmd();
1924
1925 if (cmd.add_outer_tag()) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001926 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
1927 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001928 }
1929
1930 if (cmd.remove_outer_tag()) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001931 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
1932 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001933 }
Jason Huangd33b4d82019-05-15 18:22:57 +08001934 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001935 if (cmd.trap_to_host()) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001936 OPENOLT_LOG(INFO, openolt_log_id, "action trap-to-host\n");
Craig Lutgen19512312018-11-02 10:14:46 -05001937 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, cmds_bitmask, BCMBAL_ACTION_CMD_ID_TRAP_TO_HOST);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001938 }
Jason Huangd33b4d82019-05-15 18:22:57 +08001939 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001940 if (action.o_vid()) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001941 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001942 o_vid = action.o_vid();
Jason Huangb6843dc2019-07-22 17:46:06 +08001943 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001944 }
1945
1946 if (action.o_pbits()) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001947 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
1948 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001949 }
Jason Huangd33b4d82019-05-15 18:22:57 +08001950 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001951 if (action.o_tpid()) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001952 OPENOLT_LOG(INFO, openolt_log_id, "action o_tpid=0x%04x\n", action.o_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05001953 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, o_tpid, action.o_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001954 }
Jason Huangd33b4d82019-05-15 18:22:57 +08001955 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001956 if (action.i_vid()) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001957 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
1958 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001959 }
1960
1961 if (action.i_pbits()) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001962 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
1963 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001964 }
Jason Huangd33b4d82019-05-15 18:22:57 +08001965 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001966 if (action.i_tpid()) {
Jason Huangb6843dc2019-07-22 17:46:06 +08001967 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_tpid=0x%04x\n", action.i_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05001968 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, i_tpid, action.i_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001969 }
Jason Huangd33b4d82019-05-15 18:22:57 +08001970 */
Jason Huangb6843dc2019-07-22 17:46:06 +08001971 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001972 }
1973
Shad Ansari39739bc2018-09-13 21:38:37 +00001974 if ((access_intf_id >= 0) && (onu_id >= 0)) {
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08001975 if(single_tag && ether_type == EAP_ETHER_TYPE) {
1976 tm_val.sched_id = (flow_type.compare(upstream) == 0) ? \
1977 get_default_tm_sched_id(network_intf_id, upstream) : \
1978 get_default_tm_sched_id(access_intf_id, downstream);
1979 tm_val.queue_id = 0;
Jason Huangd33b4d82019-05-15 18:22:57 +08001980
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08001981 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
Jason Huangb6843dc2019-07-22 17:46:06 +08001982 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1983 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08001984
1985 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1986 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
1987 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1988 } else {
1989 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
1990 tm_val.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, downstream);
1991
1992 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1993 // Queue 0 on DS subscriber scheduler
1994 tm_val.queue_id = 0;
1995
1996 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1997 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1998 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
1999
2000 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2001 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2002 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2003
2004 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2005 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
2006 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2007
2008 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2009 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2010 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2011 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_q_set_id, tm_q_set_id);
2012
2013 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2014 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2015 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2016 }
2017 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
2018 // NNI Scheduler ID
2019 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2020 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2021 // Queue 0 on NNI scheduler
2022 tm_val.queue_id = 0;
2023 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2024 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2025 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2026
2027 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2028 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2029 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2030
2031 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2032 /* Fetch TM QMP ID mapped to US NNI scheduler */
2033 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2034 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2035 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2036 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2037 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_q_set_id, tm_q_set_id);
2038
2039 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2040 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2041 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2042 }
2043 }
Shad Ansari39739bc2018-09-13 21:38:37 +00002044 }
Shad Ansari06101952018-07-25 00:22:09 +00002045 }
2046
Jason Huangd33b4d82019-05-15 18:22:57 +08002047 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002048 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
Jason Huangb6843dc2019-07-22 17:46:06 +08002049#ifdef FLOW_CHECKER
2050 //Flow Checker, To avoid duplicate flow.
2051 if (flow_id_counters != 0) {
2052 bool b_duplicate_flow = false;
2053 for (int flowid=0; flowid < flow_id_counters; flowid++) {
2054 int flow_index = flow_id_data[flowid][0];
2055 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(flow_index, flow_id_data[flowid][1], ONU_ID)) && \
2056 (key.flow_type == flow_id_data[flowid][1]) && \
2057 (cfg.data.svc_port_id == get_flow_status(flow_index, flow_id_data[flowid][1], SVC_PORT_ID)) && \
2058 (cfg.data.priority == get_flow_status(flow_index, flow_id_data[flowid][1], PRIORITY)) && \
2059 (cfg.data.cookie == get_flow_status(flow_index, flow_id_data[flowid][1], COOKIE)) && \
2060 (cfg.data.ingress_intf.intf_type == get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_TYPE)) && \
2061 (cfg.data.ingress_intf.intf_id == get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_ID)) && \
2062 (cfg.data.egress_intf.intf_type == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_TYPE)) && \
2063 (cfg.data.egress_intf.intf_id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_ID)) && \
2064 (c_val.o_vid == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_VID)) && \
2065 (c_val.o_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_PBITS)) && \
2066 (c_val.i_vid == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_VID)) && \
2067 (c_val.i_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_PBITS)) && \
2068 (c_val.ether_type == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_ETHER_TYPE)) && \
2069 (c_val.ip_proto == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_IP_PROTO)) && \
2070 (c_val.src_port == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_SRC_PORT)) && \
2071 (c_val.dst_port == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_DST_PORT)) && \
2072 (c_val.pkt_tag_type == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_PKT_TAG_TYPE)) && \
2073 (cfg.data.egress_qos.type == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TYPE)) && \
2074 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_QUEUE_ID)) && \
2075 (cfg.data.egress_qos.tm_sched.id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TM_SCHED_ID)) && \
2076 (a_val.cmds_bitmask == get_flow_status(flowid, flow_id_data[flowid][1], ACTION_CMDS_BITMASK)) && \
2077 (a_val.o_vid == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_VID)) && \
2078 (a_val.i_vid == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_VID)) && \
2079 (a_val.o_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_PBITS)) && \
2080 (a_val.i_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_PBITS)) && \
2081 (cfg.data.state == get_flow_status(flowid, flow_id_data[flowid][1], STATE));
2082#ifdef SHOW_FLOW_PARAM
2083 // Flow Parameter
2084 FLOW_PARAM_LOG();
2085#endif
2086
2087 if (b_duplicate_flow) {
2088 FLOW_LOG(WARNING, "Flow duplicate", 0);
2089 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
2090 }
2091 }
2092 }
2093#endif
2094
Jason Huangd33b4d82019-05-15 18:22:57 +08002095 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04002096 if (err) {
Jason Huangb6843dc2019-07-22 17:46:06 +08002097 FLOW_LOG(ERROR, "Flow add failed", err);
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04002098 return bcm_to_grpc_err(err, "flow add failed");
Jason Huangb6843dc2019-07-22 17:46:06 +08002099 } else {
2100 FLOW_LOG(INFO, "Flow add ok", err);
2101 bcmos_fastlock_lock(&data_lock);
2102 flow_id_data[flow_id_counters][0] = key.flow_id;
2103 flow_id_data[flow_id_counters][1] = key.flow_type;
2104 flow_id_counters += 1;
2105 bcmos_fastlock_unlock(&data_lock, 0);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002106 }
2107
2108 return Status::OK;
2109}
2110
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002111Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
2112
Jason Huangd33b4d82019-05-15 18:22:57 +08002113 bcmolt_flow_cfg cfg;
2114 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002115
Jason Huangd33b4d82019-05-15 18:22:57 +08002116 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002117 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002118 if (flow_type.compare(upstream) == 0 ) {
Jason Huangd33b4d82019-05-15 18:22:57 +08002119 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002120 } else if (flow_type.compare(downstream) == 0) {
Jason Huangd33b4d82019-05-15 18:22:57 +08002121 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002122 } else {
Jason Huangb6843dc2019-07-22 17:46:06 +08002123 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002124 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
2125 }
2126
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002127 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002128 uint32_t port_no = flowid_to_port[key.flow_id];
Jason Huangd33b4d82019-05-15 18:22:57 +08002129 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002130 flowid_to_gemport.erase(key.flow_id);
2131 port_to_flows[port_no].erase(key.flow_id);
2132 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
2133 }
2134 else
2135 {
2136 flowid_to_port.erase(key.flow_id);
2137 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002138 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002139
Jason Huangd33b4d82019-05-15 18:22:57 +08002140 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002141
Jason Huangd33b4d82019-05-15 18:22:57 +08002142 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002143 if (err) {
Jason Huangb6843dc2019-07-22 17:46:06 +08002144 OPENOLT_LOG(ERROR, openolt_log_id, "Error %d while removing flow %d, %s\n",
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04002145 err, flow_id, flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002146 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
2147 }
2148
Jason Huangb6843dc2019-07-22 17:46:06 +08002149 bcmos_fastlock_lock(&data_lock);
2150 for (int flowid=0; flowid < flow_id_counters; flowid++) {
2151 if (flow_id_data[flowid][0] == flow_id && flow_id_data[flowid][1] == key.flow_type) {
2152 flow_id_counters -= 1;
2153 for (int i=flowid; i < flow_id_counters; i++) {
2154 flow_id_data[i][0] = flow_id_data[i + 1][0];
2155 flow_id_data[i][1] = flow_id_data[i + 1][1];
2156 }
2157 break;
2158 }
2159 }
2160 bcmos_fastlock_unlock(&data_lock, 0);
2161
2162 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002163 return Status::OK;
2164}
2165
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002166bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
Thiyagarajan Subramani0695c982019-06-05 07:30:50 -07002167 bcmos_errno err;
2168 bcmolt_tm_sched_cfg tm_sched_cfg;
2169 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2170 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
2171
2172 // bcmbal_tm_sched_owner
2173 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2174
2175 /**< The output of the tm_sched object instance */
2176 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
2177
2178 if (direction.compare(upstream) == 0) {
2179 // In upstream it is NNI scheduler
2180 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
2181 } else if (direction.compare(downstream) == 0) {
2182 // In downstream it is PON scheduler
2183 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2184 }
2185
2186 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2187
2188 // bcmbal_tm_sched_type
2189 // set the deafult policy to strict priority
2190 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2191
2192 // num_priorities: Max number of strict priority scheduling elements
Jason Huangb6843dc2019-07-22 17:46:06 +08002193 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Thiyagarajan Subramani0695c982019-06-05 07:30:50 -07002194
2195 // bcmbal_tm_shaping
2196 uint32_t cir = 1000000;
2197 uint32_t pir = 1000000;
2198 uint32_t burst = 65536;
Jason Huangb6843dc2019-07-22 17:46:06 +08002199 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in %s pir=%u, burst=%u\n",
Thiyagarajan Subramani0695c982019-06-05 07:30:50 -07002200 direction.c_str(), pir, burst);
2201 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2202 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2203 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2204 // BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2205 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2206 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
2207
2208 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2209 if (err) {
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002210 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err %d\n", \
2211 direction.c_str(), tm_sched_key.id, intf_id, err);
2212 return err;
Thiyagarajan Subramani0695c982019-06-05 07:30:50 -07002213 }
Thiyagarajan Subramani0695c982019-06-05 07:30:50 -07002214
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002215 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2216 direction.c_str(), tm_sched_key.id, intf_id);
2217 return BCM_ERR_OK;
Thiyagarajan Subramani0695c982019-06-05 07:30:50 -07002218}
2219
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002220bcmos_errno CreateSched(std::string direction, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t port_no,
2221 uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
2222 tech_profile::SchedulingPolicy sched_policy, tech_profile::TrafficShapingInfo tf_sh_info) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002223
2224 bcmos_errno err;
2225
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002226 if (direction == downstream) {
Thiyagarajan Subramani0695c982019-06-05 07:30:50 -07002227 bcmolt_tm_sched_cfg tm_sched_cfg;
2228 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2229 tm_sched_key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002230
Thiyagarajan Subramani0695c982019-06-05 07:30:50 -07002231 // bcmbal_tm_sched_owner
2232 // In downstream it is sub_term scheduler
2233 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002234
Thiyagarajan Subramani0695c982019-06-05 07:30:50 -07002235 /**< The output of the tm_sched object instance */
2236 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002237
Thiyagarajan Subramani0695c982019-06-05 07:30:50 -07002238 // bcmbal_tm_sched_parent
2239 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2240 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
2241 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_param.u.priority.priority, priority);
2242 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
2243 be achieved using the' virtual' type of attachment.
2244 tm_sched_owner.u.sub_term.intf_id = intf_id;
2245 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2246 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002247
Thiyagarajan Subramani0695c982019-06-05 07:30:50 -07002248 // bcmbal_tm_sched_type
2249 // set the deafult policy to strict priority
2250 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002251
Thiyagarajan Subramani0695c982019-06-05 07:30:50 -07002252 // num_priorities: Max number of strict priority scheduling elements
2253 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Jason Huangd33b4d82019-05-15 18:22:57 +08002254
Thiyagarajan Subramani0695c982019-06-05 07:30:50 -07002255 // bcmbal_tm_shaping
2256 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2257 uint32_t cir = tf_sh_info.cir();
2258 uint32_t pir = tf_sh_info.pir();
2259 uint32_t burst = tf_sh_info.pbs();
Jason Huangb6843dc2019-07-22 17:46:06 +08002260 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
Thiyagarajan Subramani0695c982019-06-05 07:30:50 -07002261 cir, pir, burst);
2262 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2263 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2264 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2265 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2266 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2267 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002268 }
2269
Thiyagarajan Subramani0695c982019-06-05 07:30:50 -07002270 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002271 if (err) {
Jason Huangb6843dc2019-07-22 17:46:06 +08002272 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
2273intf_id %d, onu_id %d, uni_id %d, port_no %u\n", tm_sched_key.id, intf_id, onu_id, \
Thiyagarajan Subramani0695c982019-06-05 07:30:50 -07002274 uni_id, port_no);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002275 return err;
2276 }
Jason Huangb6843dc2019-07-22 17:46:06 +08002277 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2278uni_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 -08002279
2280 } else { //upstream
Jason Huangd33b4d82019-05-15 18:22:57 +08002281 bcmolt_itupon_alloc_cfg cfg;
Thiyagarajan Subramani0695c982019-06-05 07:30:50 -07002282 bcmolt_itupon_alloc_key key = { };
Jason Huangd33b4d82019-05-15 18:22:57 +08002283 key.pon_ni = intf_id;
2284 key.alloc_id = alloc_id;
Jason Huangb6843dc2019-07-22 17:46:06 +08002285 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
2286 int pir_bw = tf_sh_info.pir();
2287 int cir_bw = tf_sh_info.cir();
2288 //offset to match bandwidth granularity
2289 int offset_pir_bw = pir_bw%bw_granularity;
2290 int offset_cir_bw = cir_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002291
Jason Huangb6843dc2019-07-22 17:46:06 +08002292 pir_bw = pir_bw - offset_pir_bw;
2293 cir_bw = cir_bw - offset_cir_bw;
2294
2295 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
2296
2297 switch (additional_bw) {
2298 case 2: //AdditionalBW_BestEffort
2299 if (pir_bw == 0) {
2300 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2301%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2302 } else if (pir_bw < cir_bw) {
2303 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2304bandwidth (%d)\n", pir_bw, cir_bw);
2305 return BCM_ERR_PARM;
2306 } else if (pir_bw == cir_bw) {
2307 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2308bandwidth for additional bandwidth eligibility of type best_effort\n");
2309 return BCM_ERR_PARM;
2310 }
2311 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2312 break;
2313 case 1: //AdditionalBW_NA
2314 if (pir_bw == 0) {
2315 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2316%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2317 return BCM_ERR_PARM;
2318 } else if (cir_bw == 0) {
2319 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2320additional bandwidth eligibility of type Non-Assured (NA)\n");
2321 return BCM_ERR_PARM;
2322 } else if (pir_bw < cir_bw) {
2323 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2324bandwidth (%d)\n", pir_bw, cir_bw);
2325 return BCM_ERR_PARM;
2326 } else if (pir_bw == cir_bw) {
2327 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2328bandwidth for additional bandwidth eligibility of type non_assured\n");
2329 return BCM_ERR_PARM;
2330 }
2331 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2332 break;
2333 case 0: //AdditionalBW_None
2334 if (pir_bw == 0) {
2335 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
233616000 bytes/sec\n");
2337 return BCM_ERR_PARM;
2338 } else if (cir_bw == 0) {
2339 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2340for additional bandwidth eligibility of type None\n");
2341 return BCM_ERR_PARM;
2342 } else if (pir_bw > cir_bw) {
2343 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2344for additional bandwidth eligibility of type None\n");
2345 OPENOLT_LOG(ERROR, openolt_log_id, "set Maximum bandwidth (%d) to Guaranteed \
2346bandwidth in None eligibility\n", pir_bw);
2347 cir_bw = pir_bw;
2348 } else if (pir_bw < cir_bw) {
2349 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2350bandwidth (%d)\n", pir_bw, cir_bw);
2351 OPENOLT_LOG(ERROR, openolt_log_id, "set Maximum bandwidth (%d) to Guaranteed \
2352bandwidth in None eligibility\n", pir_bw);
2353 cir_bw = pir_bw;
2354 }
2355 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2356 break;
2357 default:
2358 return BCM_ERR_PARM;
2359 }
2360 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
Jason Huangd33b4d82019-05-15 18:22:57 +08002361 in a fine granularity. */
2362 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
2363 /* Fixed Bandwidth with no critical requirement of shaping */
2364 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, 0);
2365 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
Jason Huangb6843dc2019-07-22 17:46:06 +08002366 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, cir_bw);
Jason Huangd33b4d82019-05-15 18:22:57 +08002367 /* Maximum allocated bandwidth allowed for this alloc ID */
Jason Huangb6843dc2019-07-22 17:46:06 +08002368 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
Jason Huangd33b4d82019-05-15 18:22:57 +08002369 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
2370 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
2371 for skipped allocations during quiet window */
2372 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2373 /**< Allocation Profile index for CBR non-RT Bandwidth */
2374 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2375 /**< Allocation Profile index for CBR RT Bandwidth */
2376 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2377 /**< Alloc ID Weight used in case of Extended DBA mode */
2378 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2379 /**< Alloc ID Priority used in case of Extended DBA mode */
2380 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
Jason Huangb6843dc2019-07-22 17:46:06 +08002381 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002382
Jason Huangb6843dc2019-07-22 17:46:06 +08002383 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002384 if (err) {
Jason Huangb6843dc2019-07-22 17:46:06 +08002385 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2386port_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 -08002387 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002388 }
Jason Huangb6843dc2019-07-22 17:46:06 +08002389 OPENOLT_LOG(INFO, openolt_log_id, "Create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d, port_no %u, \
2390alloc_id %d\n", intf_id,onu_id,uni_id,port_no,alloc_id);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002391 }
2392
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002393 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002394}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002395
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002396Status CreateTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2397 uint32_t intf_id = traffic_scheds->intf_id();
2398 uint32_t onu_id = traffic_scheds->onu_id();
2399 uint32_t uni_id = traffic_scheds->uni_id();
2400 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002401 std::string direction;
2402 unsigned int alloc_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002403 tech_profile::SchedulerConfig sched_config;
2404 tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002405 uint32_t priority;
2406 uint32_t weight;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002407 tech_profile::SchedulingPolicy sched_policy;
2408 tech_profile::TrafficShapingInfo traffic_shaping_info;
2409 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002410
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002411 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2412 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002413
2414 direction = GetDirection(traffic_sched.direction());
2415 if (direction.compare("direction-not-supported") == 0)
2416 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2417
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002418 alloc_id = traffic_sched.alloc_id();
2419 sched_config = traffic_sched.scheduler();
2420 additional_bw = sched_config.additional_bw();
2421 priority = sched_config.priority();
2422 weight = sched_config.weight();
2423 sched_policy = sched_config.sched_policy();
2424 traffic_shaping_info = traffic_sched.traffic_shaping_info();
2425 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
2426 sched_policy, traffic_shaping_info);
2427 if (err) {
2428 return bcm_to_grpc_err(err, "Failed to create scheduler");
2429 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002430 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002431 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002432}
Jonathan Davis70c21812018-07-19 15:32:10 -04002433
Jason Huangb6843dc2019-07-22 17:46:06 +08002434bcmos_errno RemoveSched(int intf_id, int onu_id, int uni_id, int alloc_id, std::string direction) {
Jonathan Davis70c21812018-07-19 15:32:10 -04002435
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002436 bcmos_errno err;
Jason Huangb6843dc2019-07-22 17:46:06 +08002437
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002438 if (direction == upstream) {
Jason Huangd33b4d82019-05-15 18:22:57 +08002439 bcmolt_itupon_alloc_cfg cfg;
2440 bcmolt_itupon_alloc_key key = { };
2441 key.pon_ni = intf_id;
Jason Huangb6843dc2019-07-22 17:46:06 +08002442 key.alloc_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002443
Jason Huangd33b4d82019-05-15 18:22:57 +08002444 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Jason Huangb6843dc2019-07-22 17:46:06 +08002445 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Jason Huangd33b4d82019-05-15 18:22:57 +08002446 if (err) {
Jason Huangb6843dc2019-07-22 17:46:06 +08002447 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler sched, direction = %s, intf_id %d, alloc_id %d, err %d\n", \
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002448 direction.c_str(), intf_id, alloc_id, err);
Jason Huangd33b4d82019-05-15 18:22:57 +08002449 return err;
2450 }
Jason Huangb6843dc2019-07-22 17:46:06 +08002451 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, intf_id %d, alloc_id %d\n", \
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002452 direction.c_str(), intf_id, alloc_id);
Jason Huangd33b4d82019-05-15 18:22:57 +08002453 } else if (direction == downstream) {
2454 bcmolt_tm_sched_cfg cfg;
2455 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002456
Jason Huangd33b4d82019-05-15 18:22:57 +08002457 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction)) {
2458 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
2459 } else {
Jason Huangb6843dc2019-07-22 17:46:06 +08002460 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
Jason Huangd33b4d82019-05-15 18:22:57 +08002461 return BCM_ERR_OK;
2462 }
2463 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2464 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2465 if (err) {
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002466 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, id %d, intf_id %d, onu_id %d\n", \
2467 direction.c_str(), key.id, intf_id, onu_id);
Jason Huangd33b4d82019-05-15 18:22:57 +08002468 return err;
2469 }
Jason Huangb6843dc2019-07-22 17:46:06 +08002470 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d\n", \
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002471 direction.c_str(), key.id, intf_id, onu_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002472 }
2473
2474 free_tm_sched_id(intf_id, onu_id, uni_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002475 return BCM_ERR_OK;
2476}
2477
2478Status RemoveTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2479 uint32_t intf_id = traffic_scheds->intf_id();
2480 uint32_t onu_id = traffic_scheds->onu_id();
2481 uint32_t uni_id = traffic_scheds->uni_id();
2482 std::string direction;
2483 bcmos_errno err;
2484
2485 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2486 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002487
2488 direction = GetDirection(traffic_sched.direction());
2489 if (direction.compare("direction-not-supported") == 0)
2490 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2491
Jason Huangb6843dc2019-07-22 17:46:06 +08002492 int alloc_id = traffic_sched.alloc_id();
2493 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002494 if (err) {
2495 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2496 }
2497 }
2498 return Status::OK;
2499}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002500
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002501bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2502 std::string direction, std::vector<uint32_t> tmq_map_profile) {
2503 bcmos_errno err;
2504 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2505 bcmolt_tm_qmp_key tm_qmp_key;
2506 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
2507
2508 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2509 if (tm_qmp_id == -1) {
2510 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed profile count is 16.\n");
2511 }
2512
2513 tm_qmp_key.id = tm_qmp_id;
2514 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2515 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2516 }
2517
2518 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2519 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2520 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
2521 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2522 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
2523
2524 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
2525 if (err) {
2526 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, id %d\n", \
2527 tm_qmp_key.id);
2528 return err;
2529 }
2530
2531 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2532 tm_qmp_key.id);
2533 return BCM_ERR_OK;
2534}
2535
2536bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2537 bcmos_errno err;
2538 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2539 bcmolt_tm_qmp_key tm_qmp_key;
2540 tm_qmp_key.id = tm_qmp_id;
2541
2542 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2543 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2544 if (err) {
2545 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, id %d\n", \
2546 tm_qmp_key.id);
2547 return err;
2548 }
2549
2550 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2551 tm_qmp_key.id);
2552 return BCM_ERR_OK;
2553}
2554
2555bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2556 bcmos_errno err;
2557
2558 /* Create 4 Queues on given PON/NNI scheduler */
2559 for (int queue_id = 0; queue_id < 4; queue_id++) {
2560 bcmolt_tm_queue_cfg tm_queue_cfg;
2561 bcmolt_tm_queue_key tm_queue_key = {};
2562 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2563 tm_queue_key.id = queue_id;
2564 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE)
2565 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2566 else
2567 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2568
2569 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2570 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2571 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2572
2573 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2574 if (err) {
2575 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s tm queue, id %d, sched_id %d, tm_q_set_id %d\n", \
2576 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2577 return err;
2578 }
2579
2580 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2581 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2582 }
2583 return BCM_ERR_OK;
2584}
2585
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002586bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t priority,
2587 uint32_t gemport_id) {
2588 bcmos_errno err;
Jason Huangd33b4d82019-05-15 18:22:57 +08002589 bcmolt_tm_queue_cfg cfg;
2590 bcmolt_tm_queue_key key = { };
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002591 OPENOLT_LOG(INFO, openolt_log_id, "creating %s queue. access_intf_id = %d, onu_id = %d, uni_id = %d \
2592gemport_id = %d\n", direction.c_str(), access_intf_id, onu_id, uni_id, gemport_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002593
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002594 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2595 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
2596
2597 if (priority > 7) {
2598 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002599 }
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002600
2601 /* FIXME: The upstream queues have to be created once only.
2602 The upstream queues on the NNI scheduler are shared by all subscribers.
2603 When the first scheduler comes in, the queues get created, and are re-used by all others.
2604 Also, these queues should be present until the last subscriber exits the system.
2605 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2606
2607 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2608 for each GEM in TECH PROFILE */
2609 key.id = queue_id_list[priority];
2610
Jason Huangb6843dc2019-07-22 17:46:06 +08002611 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
Girish Gowdru36501552019-05-01 23:47:58 -07002612
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002613 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE)
2614 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2615 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE)
2616 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2617 else
2618 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2619
Jason Huangd33b4d82019-05-15 18:22:57 +08002620 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2621 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002622
Jason Huangd33b4d82019-05-15 18:22:57 +08002623 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002624 if (err) {
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002625 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, id %d, \
2626sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err %d\n", \
2627 direction.c_str(), key.id, key.sched_id, key.tm_q_set_id, access_intf_id, onu_id, uni_id, err);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002628 return err;
2629 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002630
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002631 OPENOLT_LOG(INFO, openolt_log_id, "Created tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2632intf_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 -08002633 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002634}
2635
2636Status CreateTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2637 uint32_t intf_id = traffic_queues->intf_id();
2638 uint32_t onu_id = traffic_queues->onu_id();
2639 uint32_t uni_id = traffic_queues->uni_id();
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002640 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002641 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002642 bcmos_errno err;
2643
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002644 qos_type = (traffic_queues->traffic_queues_size() > 1) ? \
2645 BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE : BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE;
2646
2647 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2648 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2649 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2650 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2651 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
2652
2653 direction = GetDirection(traffic_queue.direction());
2654 if (direction.compare("direction-not-supported") == 0)
2655 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2656
2657 queues_priority_q[i] = traffic_queue.priority();
2658 queues_pbit_map[i] = traffic_queue.pbit_map();
2659 }
2660
2661 std::vector<uint32_t> tmq_map_profile(8, 0);
2662 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2663 queues_priority_q, COUNT_OF(queues_priority_q));
2664 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2665 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
2666
2667 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2668 if (tm_qmp_id == -1) {
2669 CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2670 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2671 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2672 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2673 }
2674 }
2675
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002676 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2677 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002678
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
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002683 err = CreateQueue(direction, intf_id, onu_id, uni_id, traffic_queue.priority(), traffic_queue.gemport_id());
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002684
Girish Gowdru36501552019-05-01 23:47:58 -07002685 // If the queue exists already, lets not return failure and break the loop.
2686 if (err && err != BCM_ERR_ALREADY) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002687 return bcm_to_grpc_err(err, "Failed to create queue");
2688 }
2689 }
2690 return Status::OK;
2691}
2692
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002693bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t priority,
2694 uint32_t gemport_id) {
Jason Huangd33b4d82019-05-15 18:22:57 +08002695 bcmolt_tm_queue_cfg cfg;
2696 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002697 bcmos_errno err;
2698
2699 if (direction == downstream) {
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002700 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction)) {
Jason Huangd33b4d82019-05-15 18:22:57 +08002701 key.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002702 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002703 } else {
Jason Huangb6843dc2019-07-22 17:46:06 +08002704 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 -08002705 return BCM_ERR_OK;
2706 }
2707 } else {
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002708 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2709 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002710 return BCM_ERR_OK;
2711 }
2712
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002713 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE)
2714 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2715 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE)
2716 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2717 else
2718 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2719
Jason Huangd33b4d82019-05-15 18:22:57 +08002720 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
Jason Huangd33b4d82019-05-15 18:22:57 +08002721 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002722 if (err) {
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002723 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, id %d, sched_id %d, \
2724tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d\n",
2725 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 -08002726 return err;
2727 }
2728
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002729 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2730intf_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 -08002731
2732 return BCM_ERR_OK;
2733}
2734
2735Status RemoveTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2736 uint32_t intf_id = traffic_queues->intf_id();
2737 uint32_t onu_id = traffic_queues->onu_id();
2738 uint32_t uni_id = traffic_queues->uni_id();
2739 uint32_t port_no = traffic_queues->port_no();
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002740 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002741 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002742 bcmos_errno err;
2743
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002744 qos_type = (traffic_queues->traffic_queues_size() > 1) ? \
2745 BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE : BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE;
2746
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002747 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2748 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002749
2750 direction = GetDirection(traffic_queue.direction());
2751 if (direction.compare("direction-not-supported") == 0)
2752 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2753
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002754 err = RemoveQueue(direction, intf_id, onu_id, uni_id, traffic_queue.priority(), traffic_queue.gemport_id());
2755 if (err) {
2756 return bcm_to_grpc_err(err, "Failed to remove queue");
2757 }
Jonathan Davis70c21812018-07-19 15:32:10 -04002758 }
2759
Thiyagarajan Subramani1f1280b2019-08-13 18:41:19 +08002760 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))) {
2761 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2762 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
2763
2764 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
2765 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
2766 RemoveTrafficQueueMappingProfile(tm_qmp_id);
2767 }
2768 }
Jonathan Davis70c21812018-07-19 15:32:10 -04002769 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04002770}