Lines Matching full:sparx5
2 /* Microchip Sparx5 Switch driver
44 static int sparx5_mact_get_status(struct sparx5 *sparx5) in sparx5_mact_get_status() argument
46 return spx5_rd(sparx5, LRN_COMMON_ACCESS_CTRL); in sparx5_mact_get_status()
49 static int sparx5_mact_wait_for_completion(struct sparx5 *sparx5) in sparx5_mact_wait_for_completion() argument
54 sparx5, val, in sparx5_mact_wait_for_completion()
59 static void sparx5_mact_select(struct sparx5 *sparx5, in sparx5_mact_select() argument
76 spx5_wr(mach, sparx5, LRN_MAC_ACCESS_CFG_0); in sparx5_mact_select()
77 spx5_wr(macl, sparx5, LRN_MAC_ACCESS_CFG_1); in sparx5_mact_select()
80 int sparx5_mact_learn(struct sparx5 *sparx5, int pgid, in sparx5_mact_learn() argument
94 mutex_lock(&sparx5->lock); in sparx5_mact_learn()
96 sparx5_mact_select(sparx5, mac, vid); in sparx5_mact_learn()
103 sparx5, LRN_MAC_ACCESS_CFG_2); in sparx5_mact_learn()
104 spx5_wr(0, sparx5, LRN_MAC_ACCESS_CFG_3); in sparx5_mact_learn()
109 sparx5, LRN_COMMON_ACCESS_CTRL); in sparx5_mact_learn()
111 ret = sparx5_mact_wait_for_completion(sparx5); in sparx5_mact_learn()
113 mutex_unlock(&sparx5->lock); in sparx5_mact_learn()
121 struct sparx5 *sparx5 = port->sparx5; in sparx5_mc_unsync() local
123 return sparx5_mact_forget(sparx5, addr, port->pvid); in sparx5_mc_unsync()
129 struct sparx5 *sparx5 = port->sparx5; in sparx5_mc_sync() local
131 return sparx5_mact_learn(sparx5, PGID_CPU, addr, port->pvid); in sparx5_mc_sync()
134 static int sparx5_mact_get(struct sparx5 *sparx5, in sparx5_mact_get() argument
141 cfg2 = spx5_rd(sparx5, LRN_MAC_ACCESS_CFG_2); in sparx5_mact_get()
143 mach = spx5_rd(sparx5, LRN_MAC_ACCESS_CFG_0); in sparx5_mact_get()
144 macl = spx5_rd(sparx5, LRN_MAC_ACCESS_CFG_1); in sparx5_mact_get()
159 bool sparx5_mact_getnext(struct sparx5 *sparx5, in sparx5_mact_getnext() argument
165 mutex_lock(&sparx5->lock); in sparx5_mact_getnext()
167 sparx5_mact_select(sparx5, mac, *vid); in sparx5_mact_getnext()
171 sparx5, LRN_SCAN_NEXT_CFG); in sparx5_mact_getnext()
175 sparx5, LRN_COMMON_ACCESS_CTRL); in sparx5_mact_getnext()
177 ret = sparx5_mact_wait_for_completion(sparx5); in sparx5_mact_getnext()
179 ret = sparx5_mact_get(sparx5, mac, vid, &cfg2); in sparx5_mact_getnext()
184 mutex_unlock(&sparx5->lock); in sparx5_mact_getnext()
189 static int sparx5_mact_lookup(struct sparx5 *sparx5, in sparx5_mact_lookup() argument
195 mutex_lock(&sparx5->lock); in sparx5_mact_lookup()
197 sparx5_mact_select(sparx5, mac, vid); in sparx5_mact_lookup()
202 sparx5, LRN_COMMON_ACCESS_CTRL); in sparx5_mact_lookup()
204 ret = sparx5_mact_wait_for_completion(sparx5); in sparx5_mact_lookup()
209 (spx5_rd(sparx5, LRN_MAC_ACCESS_CFG_2)); in sparx5_mact_lookup()
212 mutex_unlock(&sparx5->lock); in sparx5_mact_lookup()
217 int sparx5_mact_forget(struct sparx5 *sparx5, in sparx5_mact_forget() argument
222 mutex_lock(&sparx5->lock); in sparx5_mact_forget()
224 sparx5_mact_select(sparx5, mac, vid); in sparx5_mact_forget()
229 sparx5, LRN_COMMON_ACCESS_CTRL); in sparx5_mact_forget()
231 ret = sparx5_mact_wait_for_completion(sparx5); in sparx5_mact_forget()
233 mutex_unlock(&sparx5->lock); in sparx5_mact_forget()
238 static struct sparx5_mact_entry *alloc_mact_entry(struct sparx5 *sparx5, in alloc_mact_entry() argument
244 mact_entry = devm_kzalloc(sparx5->dev, in alloc_mact_entry()
255 static struct sparx5_mact_entry *find_mact_entry(struct sparx5 *sparx5, in find_mact_entry() argument
262 mutex_lock(&sparx5->mact_lock); in find_mact_entry()
263 list_for_each_entry(mact_entry, &sparx5->mact_entries, list) { in find_mact_entry()
271 mutex_unlock(&sparx5->mact_lock); in find_mact_entry()
288 int sparx5_add_mact_entry(struct sparx5 *sparx5, in sparx5_add_mact_entry() argument
295 ret = sparx5_mact_lookup(sparx5, addr, vid); in sparx5_add_mact_entry()
305 mact_entry = find_mact_entry(sparx5, addr, vid, port->portno); in sparx5_add_mact_entry()
312 mact_entry = alloc_mact_entry(sparx5, addr, vid, port->portno); in sparx5_add_mact_entry()
316 mutex_lock(&sparx5->mact_lock); in sparx5_add_mact_entry()
317 list_add_tail(&mact_entry->list, &sparx5->mact_entries); in sparx5_add_mact_entry()
318 mutex_unlock(&sparx5->mact_lock); in sparx5_add_mact_entry()
321 ret = sparx5_mact_learn(sparx5, port->portno, addr, vid); in sparx5_add_mact_entry()
333 int sparx5_del_mact_entry(struct sparx5 *sparx5, in sparx5_del_mact_entry() argument
342 mutex_lock(&sparx5->mact_lock); in sparx5_del_mact_entry()
343 list_for_each_entry_safe(mact_entry, tmp, &sparx5->mact_entries, in sparx5_del_mact_entry()
348 devm_kfree(sparx5->dev, mact_entry); in sparx5_del_mact_entry()
350 sparx5_mact_forget(sparx5, addr, mact_entry->vid); in sparx5_del_mact_entry()
353 mutex_unlock(&sparx5->mact_lock); in sparx5_del_mact_entry()
358 static void sparx5_mact_handle_entry(struct sparx5 *sparx5, in sparx5_mact_handle_entry() argument
374 if (!test_bit(port, sparx5->bridge_mask)) in sparx5_mact_handle_entry()
377 mutex_lock(&sparx5->mact_lock); in sparx5_mact_handle_entry()
378 list_for_each_entry(mact_entry, &sparx5->mact_entries, list) { in sparx5_mact_handle_entry()
384 dev_warn(sparx5->dev, "Entry move: %d -> %d\n", in sparx5_mact_handle_entry()
393 mutex_unlock(&sparx5->mact_lock); in sparx5_mact_handle_entry()
401 mact_entry = alloc_mact_entry(sparx5, mac, vid, port); in sparx5_mact_handle_entry()
406 mutex_lock(&sparx5->mact_lock); in sparx5_mact_handle_entry()
407 list_add_tail(&mact_entry->list, &sparx5->mact_entries); in sparx5_mact_handle_entry()
408 mutex_unlock(&sparx5->mact_lock); in sparx5_mact_handle_entry()
413 mac, vid, sparx5->ports[port]->ndev, in sparx5_mact_handle_entry()
420 struct sparx5 *sparx5 = container_of(del_work, struct sparx5, in sparx5_mact_pull_work() local
429 mutex_lock(&sparx5->mact_lock); in sparx5_mact_pull_work()
430 list_for_each_entry(mact_entry, &sparx5->mact_entries, list) in sparx5_mact_pull_work()
432 mutex_unlock(&sparx5->mact_lock); in sparx5_mact_pull_work()
438 mutex_lock(&sparx5->lock); in sparx5_mact_pull_work()
439 sparx5_mact_select(sparx5, mac, vid); in sparx5_mact_pull_work()
441 sparx5, LRN_SCAN_NEXT_CFG); in sparx5_mact_pull_work()
445 sparx5, LRN_COMMON_ACCESS_CTRL); in sparx5_mact_pull_work()
446 ret = sparx5_mact_wait_for_completion(sparx5); in sparx5_mact_pull_work()
448 ret = sparx5_mact_get(sparx5, mac, &vid, &cfg2); in sparx5_mact_pull_work()
449 mutex_unlock(&sparx5->lock); in sparx5_mact_pull_work()
451 sparx5_mact_handle_entry(sparx5, mac, vid, cfg2); in sparx5_mact_pull_work()
454 mutex_lock(&sparx5->mact_lock); in sparx5_mact_pull_work()
455 list_for_each_entry_safe(mact_entry, tmp, &sparx5->mact_entries, in sparx5_mact_pull_work()
463 sparx5->ports[mact_entry->port]->ndev, in sparx5_mact_pull_work()
467 devm_kfree(sparx5->dev, mact_entry); in sparx5_mact_pull_work()
469 mutex_unlock(&sparx5->mact_lock); in sparx5_mact_pull_work()
471 queue_delayed_work(sparx5->mact_queue, &sparx5->mact_work, in sparx5_mact_pull_work()
475 void sparx5_set_ageing(struct sparx5 *sparx5, int msecs) in sparx5_set_ageing() argument
483 sparx5, in sparx5_set_ageing()
487 void sparx5_mact_init(struct sparx5 *sparx5) in sparx5_mact_init() argument
489 mutex_init(&sparx5->lock); in sparx5_mact_init()
494 sparx5, LRN_COMMON_ACCESS_CTRL); in sparx5_mact_init()
496 if (sparx5_mact_wait_for_completion(sparx5) != 0) in sparx5_mact_init()
497 dev_warn(sparx5->dev, "MAC flush error\n"); in sparx5_mact_init()
499 sparx5_set_ageing(sparx5, BR_DEFAULT_AGEING_TIME / HZ * 1000); in sparx5_mact_init()