1adfc5217SJeff Kirsher /* bnx2x_sp.c: Broadcom Everest network driver. 2adfc5217SJeff Kirsher * 3adfc5217SJeff Kirsher * Copyright 2011 Broadcom Corporation 4adfc5217SJeff Kirsher * 5adfc5217SJeff Kirsher * Unless you and Broadcom execute a separate written software license 6adfc5217SJeff Kirsher * agreement governing use of this software, this software is licensed to you 7adfc5217SJeff Kirsher * under the terms of the GNU General Public License version 2, available 8adfc5217SJeff Kirsher * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL"). 9adfc5217SJeff Kirsher * 10adfc5217SJeff Kirsher * Notwithstanding the above, under no circumstances may you combine this 11adfc5217SJeff Kirsher * software in any way with any other Broadcom software provided under a 12adfc5217SJeff Kirsher * license other than the GPL, without Broadcom's express prior written 13adfc5217SJeff Kirsher * consent. 14adfc5217SJeff Kirsher * 15adfc5217SJeff Kirsher * Maintained by: Eilon Greenstein <eilong@broadcom.com> 16adfc5217SJeff Kirsher * Written by: Vladislav Zolotarov 17adfc5217SJeff Kirsher * 18adfc5217SJeff Kirsher */ 19f1deab50SJoe Perches 20f1deab50SJoe Perches #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 21f1deab50SJoe Perches 22adfc5217SJeff Kirsher #include <linux/module.h> 23adfc5217SJeff Kirsher #include <linux/crc32.h> 24adfc5217SJeff Kirsher #include <linux/netdevice.h> 25adfc5217SJeff Kirsher #include <linux/etherdevice.h> 26adfc5217SJeff Kirsher #include <linux/crc32c.h> 27adfc5217SJeff Kirsher #include "bnx2x.h" 28adfc5217SJeff Kirsher #include "bnx2x_cmn.h" 29adfc5217SJeff Kirsher #include "bnx2x_sp.h" 30adfc5217SJeff Kirsher 31adfc5217SJeff Kirsher #define BNX2X_MAX_EMUL_MULTI 16 32adfc5217SJeff Kirsher 33adfc5217SJeff Kirsher /**** Exe Queue interfaces ****/ 34adfc5217SJeff Kirsher 35adfc5217SJeff Kirsher /** 36adfc5217SJeff Kirsher * bnx2x_exe_queue_init - init the Exe Queue object 37adfc5217SJeff Kirsher * 38adfc5217SJeff Kirsher * @o: poiter to the object 39adfc5217SJeff Kirsher * @exe_len: length 40adfc5217SJeff Kirsher * @owner: poiter to the owner 41adfc5217SJeff Kirsher * @validate: validate function pointer 42adfc5217SJeff Kirsher * @optimize: optimize function pointer 43adfc5217SJeff Kirsher * @exec: execute function pointer 44adfc5217SJeff Kirsher * @get: get function pointer 45adfc5217SJeff Kirsher */ 46adfc5217SJeff Kirsher static inline void bnx2x_exe_queue_init(struct bnx2x *bp, 47adfc5217SJeff Kirsher struct bnx2x_exe_queue_obj *o, 48adfc5217SJeff Kirsher int exe_len, 49adfc5217SJeff Kirsher union bnx2x_qable_obj *owner, 50adfc5217SJeff Kirsher exe_q_validate validate, 51adfc5217SJeff Kirsher exe_q_optimize optimize, 52adfc5217SJeff Kirsher exe_q_execute exec, 53adfc5217SJeff Kirsher exe_q_get get) 54adfc5217SJeff Kirsher { 55adfc5217SJeff Kirsher memset(o, 0, sizeof(*o)); 56adfc5217SJeff Kirsher 57adfc5217SJeff Kirsher INIT_LIST_HEAD(&o->exe_queue); 58adfc5217SJeff Kirsher INIT_LIST_HEAD(&o->pending_comp); 59adfc5217SJeff Kirsher 60adfc5217SJeff Kirsher spin_lock_init(&o->lock); 61adfc5217SJeff Kirsher 62adfc5217SJeff Kirsher o->exe_chunk_len = exe_len; 63adfc5217SJeff Kirsher o->owner = owner; 64adfc5217SJeff Kirsher 65adfc5217SJeff Kirsher /* Owner specific callbacks */ 66adfc5217SJeff Kirsher o->validate = validate; 67adfc5217SJeff Kirsher o->optimize = optimize; 68adfc5217SJeff Kirsher o->execute = exec; 69adfc5217SJeff Kirsher o->get = get; 70adfc5217SJeff Kirsher 71adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "Setup the execution queue with the chunk " 72adfc5217SJeff Kirsher "length of %d\n", exe_len); 73adfc5217SJeff Kirsher } 74adfc5217SJeff Kirsher 75adfc5217SJeff Kirsher static inline void bnx2x_exe_queue_free_elem(struct bnx2x *bp, 76adfc5217SJeff Kirsher struct bnx2x_exeq_elem *elem) 77adfc5217SJeff Kirsher { 78adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "Deleting an exe_queue element\n"); 79adfc5217SJeff Kirsher kfree(elem); 80adfc5217SJeff Kirsher } 81adfc5217SJeff Kirsher 82adfc5217SJeff Kirsher static inline int bnx2x_exe_queue_length(struct bnx2x_exe_queue_obj *o) 83adfc5217SJeff Kirsher { 84adfc5217SJeff Kirsher struct bnx2x_exeq_elem *elem; 85adfc5217SJeff Kirsher int cnt = 0; 86adfc5217SJeff Kirsher 87adfc5217SJeff Kirsher spin_lock_bh(&o->lock); 88adfc5217SJeff Kirsher 89adfc5217SJeff Kirsher list_for_each_entry(elem, &o->exe_queue, link) 90adfc5217SJeff Kirsher cnt++; 91adfc5217SJeff Kirsher 92adfc5217SJeff Kirsher spin_unlock_bh(&o->lock); 93adfc5217SJeff Kirsher 94adfc5217SJeff Kirsher return cnt; 95adfc5217SJeff Kirsher } 96adfc5217SJeff Kirsher 97adfc5217SJeff Kirsher /** 98adfc5217SJeff Kirsher * bnx2x_exe_queue_add - add a new element to the execution queue 99adfc5217SJeff Kirsher * 100adfc5217SJeff Kirsher * @bp: driver handle 101adfc5217SJeff Kirsher * @o: queue 102adfc5217SJeff Kirsher * @cmd: new command to add 103adfc5217SJeff Kirsher * @restore: true - do not optimize the command 104adfc5217SJeff Kirsher * 105adfc5217SJeff Kirsher * If the element is optimized or is illegal, frees it. 106adfc5217SJeff Kirsher */ 107adfc5217SJeff Kirsher static inline int bnx2x_exe_queue_add(struct bnx2x *bp, 108adfc5217SJeff Kirsher struct bnx2x_exe_queue_obj *o, 109adfc5217SJeff Kirsher struct bnx2x_exeq_elem *elem, 110adfc5217SJeff Kirsher bool restore) 111adfc5217SJeff Kirsher { 112adfc5217SJeff Kirsher int rc; 113adfc5217SJeff Kirsher 114adfc5217SJeff Kirsher spin_lock_bh(&o->lock); 115adfc5217SJeff Kirsher 116adfc5217SJeff Kirsher if (!restore) { 117adfc5217SJeff Kirsher /* Try to cancel this element queue */ 118adfc5217SJeff Kirsher rc = o->optimize(bp, o->owner, elem); 119adfc5217SJeff Kirsher if (rc) 120adfc5217SJeff Kirsher goto free_and_exit; 121adfc5217SJeff Kirsher 122adfc5217SJeff Kirsher /* Check if this request is ok */ 123adfc5217SJeff Kirsher rc = o->validate(bp, o->owner, elem); 124adfc5217SJeff Kirsher if (rc) { 125adfc5217SJeff Kirsher BNX2X_ERR("Preamble failed: %d\n", rc); 126adfc5217SJeff Kirsher goto free_and_exit; 127adfc5217SJeff Kirsher } 128adfc5217SJeff Kirsher } 129adfc5217SJeff Kirsher 130adfc5217SJeff Kirsher /* If so, add it to the execution queue */ 131adfc5217SJeff Kirsher list_add_tail(&elem->link, &o->exe_queue); 132adfc5217SJeff Kirsher 133adfc5217SJeff Kirsher spin_unlock_bh(&o->lock); 134adfc5217SJeff Kirsher 135adfc5217SJeff Kirsher return 0; 136adfc5217SJeff Kirsher 137adfc5217SJeff Kirsher free_and_exit: 138adfc5217SJeff Kirsher bnx2x_exe_queue_free_elem(bp, elem); 139adfc5217SJeff Kirsher 140adfc5217SJeff Kirsher spin_unlock_bh(&o->lock); 141adfc5217SJeff Kirsher 142adfc5217SJeff Kirsher return rc; 143adfc5217SJeff Kirsher 144adfc5217SJeff Kirsher } 145adfc5217SJeff Kirsher 146adfc5217SJeff Kirsher static inline void __bnx2x_exe_queue_reset_pending( 147adfc5217SJeff Kirsher struct bnx2x *bp, 148adfc5217SJeff Kirsher struct bnx2x_exe_queue_obj *o) 149adfc5217SJeff Kirsher { 150adfc5217SJeff Kirsher struct bnx2x_exeq_elem *elem; 151adfc5217SJeff Kirsher 152adfc5217SJeff Kirsher while (!list_empty(&o->pending_comp)) { 153adfc5217SJeff Kirsher elem = list_first_entry(&o->pending_comp, 154adfc5217SJeff Kirsher struct bnx2x_exeq_elem, link); 155adfc5217SJeff Kirsher 156adfc5217SJeff Kirsher list_del(&elem->link); 157adfc5217SJeff Kirsher bnx2x_exe_queue_free_elem(bp, elem); 158adfc5217SJeff Kirsher } 159adfc5217SJeff Kirsher } 160adfc5217SJeff Kirsher 161adfc5217SJeff Kirsher static inline void bnx2x_exe_queue_reset_pending(struct bnx2x *bp, 162adfc5217SJeff Kirsher struct bnx2x_exe_queue_obj *o) 163adfc5217SJeff Kirsher { 164adfc5217SJeff Kirsher 165adfc5217SJeff Kirsher spin_lock_bh(&o->lock); 166adfc5217SJeff Kirsher 167adfc5217SJeff Kirsher __bnx2x_exe_queue_reset_pending(bp, o); 168adfc5217SJeff Kirsher 169adfc5217SJeff Kirsher spin_unlock_bh(&o->lock); 170adfc5217SJeff Kirsher 171adfc5217SJeff Kirsher } 172adfc5217SJeff Kirsher 173adfc5217SJeff Kirsher /** 174adfc5217SJeff Kirsher * bnx2x_exe_queue_step - execute one execution chunk atomically 175adfc5217SJeff Kirsher * 176adfc5217SJeff Kirsher * @bp: driver handle 177adfc5217SJeff Kirsher * @o: queue 178adfc5217SJeff Kirsher * @ramrod_flags: flags 179adfc5217SJeff Kirsher * 180adfc5217SJeff Kirsher * (Atomicy is ensured using the exe_queue->lock). 181adfc5217SJeff Kirsher */ 182adfc5217SJeff Kirsher static inline int bnx2x_exe_queue_step(struct bnx2x *bp, 183adfc5217SJeff Kirsher struct bnx2x_exe_queue_obj *o, 184adfc5217SJeff Kirsher unsigned long *ramrod_flags) 185adfc5217SJeff Kirsher { 186adfc5217SJeff Kirsher struct bnx2x_exeq_elem *elem, spacer; 187adfc5217SJeff Kirsher int cur_len = 0, rc; 188adfc5217SJeff Kirsher 189adfc5217SJeff Kirsher memset(&spacer, 0, sizeof(spacer)); 190adfc5217SJeff Kirsher 191adfc5217SJeff Kirsher spin_lock_bh(&o->lock); 192adfc5217SJeff Kirsher 193adfc5217SJeff Kirsher /* 194adfc5217SJeff Kirsher * Next step should not be performed until the current is finished, 195adfc5217SJeff Kirsher * unless a DRV_CLEAR_ONLY bit is set. In this case we just want to 196adfc5217SJeff Kirsher * properly clear object internals without sending any command to the FW 197adfc5217SJeff Kirsher * which also implies there won't be any completion to clear the 198adfc5217SJeff Kirsher * 'pending' list. 199adfc5217SJeff Kirsher */ 200adfc5217SJeff Kirsher if (!list_empty(&o->pending_comp)) { 201adfc5217SJeff Kirsher if (test_bit(RAMROD_DRV_CLR_ONLY, ramrod_flags)) { 202adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "RAMROD_DRV_CLR_ONLY requested: " 203adfc5217SJeff Kirsher "resetting pending_comp\n"); 204adfc5217SJeff Kirsher __bnx2x_exe_queue_reset_pending(bp, o); 205adfc5217SJeff Kirsher } else { 206adfc5217SJeff Kirsher spin_unlock_bh(&o->lock); 207adfc5217SJeff Kirsher return 1; 208adfc5217SJeff Kirsher } 209adfc5217SJeff Kirsher } 210adfc5217SJeff Kirsher 211adfc5217SJeff Kirsher /* 212adfc5217SJeff Kirsher * Run through the pending commands list and create a next 213adfc5217SJeff Kirsher * execution chunk. 214adfc5217SJeff Kirsher */ 215adfc5217SJeff Kirsher while (!list_empty(&o->exe_queue)) { 216adfc5217SJeff Kirsher elem = list_first_entry(&o->exe_queue, struct bnx2x_exeq_elem, 217adfc5217SJeff Kirsher link); 218adfc5217SJeff Kirsher WARN_ON(!elem->cmd_len); 219adfc5217SJeff Kirsher 220adfc5217SJeff Kirsher if (cur_len + elem->cmd_len <= o->exe_chunk_len) { 221adfc5217SJeff Kirsher cur_len += elem->cmd_len; 222adfc5217SJeff Kirsher /* 223adfc5217SJeff Kirsher * Prevent from both lists being empty when moving an 224adfc5217SJeff Kirsher * element. This will allow the call of 225adfc5217SJeff Kirsher * bnx2x_exe_queue_empty() without locking. 226adfc5217SJeff Kirsher */ 227adfc5217SJeff Kirsher list_add_tail(&spacer.link, &o->pending_comp); 228adfc5217SJeff Kirsher mb(); 229adfc5217SJeff Kirsher list_del(&elem->link); 230adfc5217SJeff Kirsher list_add_tail(&elem->link, &o->pending_comp); 231adfc5217SJeff Kirsher list_del(&spacer.link); 232adfc5217SJeff Kirsher } else 233adfc5217SJeff Kirsher break; 234adfc5217SJeff Kirsher } 235adfc5217SJeff Kirsher 236adfc5217SJeff Kirsher /* Sanity check */ 237adfc5217SJeff Kirsher if (!cur_len) { 238adfc5217SJeff Kirsher spin_unlock_bh(&o->lock); 239adfc5217SJeff Kirsher return 0; 240adfc5217SJeff Kirsher } 241adfc5217SJeff Kirsher 242adfc5217SJeff Kirsher rc = o->execute(bp, o->owner, &o->pending_comp, ramrod_flags); 243adfc5217SJeff Kirsher if (rc < 0) 244adfc5217SJeff Kirsher /* 245adfc5217SJeff Kirsher * In case of an error return the commands back to the queue 246adfc5217SJeff Kirsher * and reset the pending_comp. 247adfc5217SJeff Kirsher */ 248adfc5217SJeff Kirsher list_splice_init(&o->pending_comp, &o->exe_queue); 249adfc5217SJeff Kirsher else if (!rc) 250adfc5217SJeff Kirsher /* 251adfc5217SJeff Kirsher * If zero is returned, means there are no outstanding pending 252adfc5217SJeff Kirsher * completions and we may dismiss the pending list. 253adfc5217SJeff Kirsher */ 254adfc5217SJeff Kirsher __bnx2x_exe_queue_reset_pending(bp, o); 255adfc5217SJeff Kirsher 256adfc5217SJeff Kirsher spin_unlock_bh(&o->lock); 257adfc5217SJeff Kirsher return rc; 258adfc5217SJeff Kirsher } 259adfc5217SJeff Kirsher 260adfc5217SJeff Kirsher static inline bool bnx2x_exe_queue_empty(struct bnx2x_exe_queue_obj *o) 261adfc5217SJeff Kirsher { 262adfc5217SJeff Kirsher bool empty = list_empty(&o->exe_queue); 263adfc5217SJeff Kirsher 264adfc5217SJeff Kirsher /* Don't reorder!!! */ 265adfc5217SJeff Kirsher mb(); 266adfc5217SJeff Kirsher 267adfc5217SJeff Kirsher return empty && list_empty(&o->pending_comp); 268adfc5217SJeff Kirsher } 269adfc5217SJeff Kirsher 270adfc5217SJeff Kirsher static inline struct bnx2x_exeq_elem *bnx2x_exe_queue_alloc_elem( 271adfc5217SJeff Kirsher struct bnx2x *bp) 272adfc5217SJeff Kirsher { 273adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "Allocating a new exe_queue element\n"); 274adfc5217SJeff Kirsher return kzalloc(sizeof(struct bnx2x_exeq_elem), GFP_ATOMIC); 275adfc5217SJeff Kirsher } 276adfc5217SJeff Kirsher 277adfc5217SJeff Kirsher /************************ raw_obj functions ***********************************/ 278adfc5217SJeff Kirsher static bool bnx2x_raw_check_pending(struct bnx2x_raw_obj *o) 279adfc5217SJeff Kirsher { 280adfc5217SJeff Kirsher return !!test_bit(o->state, o->pstate); 281adfc5217SJeff Kirsher } 282adfc5217SJeff Kirsher 283adfc5217SJeff Kirsher static void bnx2x_raw_clear_pending(struct bnx2x_raw_obj *o) 284adfc5217SJeff Kirsher { 285adfc5217SJeff Kirsher smp_mb__before_clear_bit(); 286adfc5217SJeff Kirsher clear_bit(o->state, o->pstate); 287adfc5217SJeff Kirsher smp_mb__after_clear_bit(); 288adfc5217SJeff Kirsher } 289adfc5217SJeff Kirsher 290adfc5217SJeff Kirsher static void bnx2x_raw_set_pending(struct bnx2x_raw_obj *o) 291adfc5217SJeff Kirsher { 292adfc5217SJeff Kirsher smp_mb__before_clear_bit(); 293adfc5217SJeff Kirsher set_bit(o->state, o->pstate); 294adfc5217SJeff Kirsher smp_mb__after_clear_bit(); 295adfc5217SJeff Kirsher } 296adfc5217SJeff Kirsher 297adfc5217SJeff Kirsher /** 298adfc5217SJeff Kirsher * bnx2x_state_wait - wait until the given bit(state) is cleared 299adfc5217SJeff Kirsher * 300adfc5217SJeff Kirsher * @bp: device handle 301adfc5217SJeff Kirsher * @state: state which is to be cleared 302adfc5217SJeff Kirsher * @state_p: state buffer 303adfc5217SJeff Kirsher * 304adfc5217SJeff Kirsher */ 305adfc5217SJeff Kirsher static inline int bnx2x_state_wait(struct bnx2x *bp, int state, 306adfc5217SJeff Kirsher unsigned long *pstate) 307adfc5217SJeff Kirsher { 308adfc5217SJeff Kirsher /* can take a while if any port is running */ 309adfc5217SJeff Kirsher int cnt = 5000; 310adfc5217SJeff Kirsher 311adfc5217SJeff Kirsher 312adfc5217SJeff Kirsher if (CHIP_REV_IS_EMUL(bp)) 313adfc5217SJeff Kirsher cnt *= 20; 314adfc5217SJeff Kirsher 315adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "waiting for state to become %d\n", state); 316adfc5217SJeff Kirsher 317adfc5217SJeff Kirsher might_sleep(); 318adfc5217SJeff Kirsher while (cnt--) { 319adfc5217SJeff Kirsher if (!test_bit(state, pstate)) { 320adfc5217SJeff Kirsher #ifdef BNX2X_STOP_ON_ERROR 321adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "exit (cnt %d)\n", 5000 - cnt); 322adfc5217SJeff Kirsher #endif 323adfc5217SJeff Kirsher return 0; 324adfc5217SJeff Kirsher } 325adfc5217SJeff Kirsher 326adfc5217SJeff Kirsher usleep_range(1000, 1000); 327adfc5217SJeff Kirsher 328adfc5217SJeff Kirsher if (bp->panic) 329adfc5217SJeff Kirsher return -EIO; 330adfc5217SJeff Kirsher } 331adfc5217SJeff Kirsher 332adfc5217SJeff Kirsher /* timeout! */ 333adfc5217SJeff Kirsher BNX2X_ERR("timeout waiting for state %d\n", state); 334adfc5217SJeff Kirsher #ifdef BNX2X_STOP_ON_ERROR 335adfc5217SJeff Kirsher bnx2x_panic(); 336adfc5217SJeff Kirsher #endif 337adfc5217SJeff Kirsher 338adfc5217SJeff Kirsher return -EBUSY; 339adfc5217SJeff Kirsher } 340adfc5217SJeff Kirsher 341adfc5217SJeff Kirsher static int bnx2x_raw_wait(struct bnx2x *bp, struct bnx2x_raw_obj *raw) 342adfc5217SJeff Kirsher { 343adfc5217SJeff Kirsher return bnx2x_state_wait(bp, raw->state, raw->pstate); 344adfc5217SJeff Kirsher } 345adfc5217SJeff Kirsher 346adfc5217SJeff Kirsher /***************** Classification verbs: Set/Del MAC/VLAN/VLAN-MAC ************/ 347adfc5217SJeff Kirsher /* credit handling callbacks */ 348adfc5217SJeff Kirsher static bool bnx2x_get_cam_offset_mac(struct bnx2x_vlan_mac_obj *o, int *offset) 349adfc5217SJeff Kirsher { 350adfc5217SJeff Kirsher struct bnx2x_credit_pool_obj *mp = o->macs_pool; 351adfc5217SJeff Kirsher 352adfc5217SJeff Kirsher WARN_ON(!mp); 353adfc5217SJeff Kirsher 354adfc5217SJeff Kirsher return mp->get_entry(mp, offset); 355adfc5217SJeff Kirsher } 356adfc5217SJeff Kirsher 357adfc5217SJeff Kirsher static bool bnx2x_get_credit_mac(struct bnx2x_vlan_mac_obj *o) 358adfc5217SJeff Kirsher { 359adfc5217SJeff Kirsher struct bnx2x_credit_pool_obj *mp = o->macs_pool; 360adfc5217SJeff Kirsher 361adfc5217SJeff Kirsher WARN_ON(!mp); 362adfc5217SJeff Kirsher 363adfc5217SJeff Kirsher return mp->get(mp, 1); 364adfc5217SJeff Kirsher } 365adfc5217SJeff Kirsher 366adfc5217SJeff Kirsher static bool bnx2x_get_cam_offset_vlan(struct bnx2x_vlan_mac_obj *o, int *offset) 367adfc5217SJeff Kirsher { 368adfc5217SJeff Kirsher struct bnx2x_credit_pool_obj *vp = o->vlans_pool; 369adfc5217SJeff Kirsher 370adfc5217SJeff Kirsher WARN_ON(!vp); 371adfc5217SJeff Kirsher 372adfc5217SJeff Kirsher return vp->get_entry(vp, offset); 373adfc5217SJeff Kirsher } 374adfc5217SJeff Kirsher 375adfc5217SJeff Kirsher static bool bnx2x_get_credit_vlan(struct bnx2x_vlan_mac_obj *o) 376adfc5217SJeff Kirsher { 377adfc5217SJeff Kirsher struct bnx2x_credit_pool_obj *vp = o->vlans_pool; 378adfc5217SJeff Kirsher 379adfc5217SJeff Kirsher WARN_ON(!vp); 380adfc5217SJeff Kirsher 381adfc5217SJeff Kirsher return vp->get(vp, 1); 382adfc5217SJeff Kirsher } 383adfc5217SJeff Kirsher 384adfc5217SJeff Kirsher static bool bnx2x_get_credit_vlan_mac(struct bnx2x_vlan_mac_obj *o) 385adfc5217SJeff Kirsher { 386adfc5217SJeff Kirsher struct bnx2x_credit_pool_obj *mp = o->macs_pool; 387adfc5217SJeff Kirsher struct bnx2x_credit_pool_obj *vp = o->vlans_pool; 388adfc5217SJeff Kirsher 389adfc5217SJeff Kirsher if (!mp->get(mp, 1)) 390adfc5217SJeff Kirsher return false; 391adfc5217SJeff Kirsher 392adfc5217SJeff Kirsher if (!vp->get(vp, 1)) { 393adfc5217SJeff Kirsher mp->put(mp, 1); 394adfc5217SJeff Kirsher return false; 395adfc5217SJeff Kirsher } 396adfc5217SJeff Kirsher 397adfc5217SJeff Kirsher return true; 398adfc5217SJeff Kirsher } 399adfc5217SJeff Kirsher 400adfc5217SJeff Kirsher static bool bnx2x_put_cam_offset_mac(struct bnx2x_vlan_mac_obj *o, int offset) 401adfc5217SJeff Kirsher { 402adfc5217SJeff Kirsher struct bnx2x_credit_pool_obj *mp = o->macs_pool; 403adfc5217SJeff Kirsher 404adfc5217SJeff Kirsher return mp->put_entry(mp, offset); 405adfc5217SJeff Kirsher } 406adfc5217SJeff Kirsher 407adfc5217SJeff Kirsher static bool bnx2x_put_credit_mac(struct bnx2x_vlan_mac_obj *o) 408adfc5217SJeff Kirsher { 409adfc5217SJeff Kirsher struct bnx2x_credit_pool_obj *mp = o->macs_pool; 410adfc5217SJeff Kirsher 411adfc5217SJeff Kirsher return mp->put(mp, 1); 412adfc5217SJeff Kirsher } 413adfc5217SJeff Kirsher 414adfc5217SJeff Kirsher static bool bnx2x_put_cam_offset_vlan(struct bnx2x_vlan_mac_obj *o, int offset) 415adfc5217SJeff Kirsher { 416adfc5217SJeff Kirsher struct bnx2x_credit_pool_obj *vp = o->vlans_pool; 417adfc5217SJeff Kirsher 418adfc5217SJeff Kirsher return vp->put_entry(vp, offset); 419adfc5217SJeff Kirsher } 420adfc5217SJeff Kirsher 421adfc5217SJeff Kirsher static bool bnx2x_put_credit_vlan(struct bnx2x_vlan_mac_obj *o) 422adfc5217SJeff Kirsher { 423adfc5217SJeff Kirsher struct bnx2x_credit_pool_obj *vp = o->vlans_pool; 424adfc5217SJeff Kirsher 425adfc5217SJeff Kirsher return vp->put(vp, 1); 426adfc5217SJeff Kirsher } 427adfc5217SJeff Kirsher 428adfc5217SJeff Kirsher static bool bnx2x_put_credit_vlan_mac(struct bnx2x_vlan_mac_obj *o) 429adfc5217SJeff Kirsher { 430adfc5217SJeff Kirsher struct bnx2x_credit_pool_obj *mp = o->macs_pool; 431adfc5217SJeff Kirsher struct bnx2x_credit_pool_obj *vp = o->vlans_pool; 432adfc5217SJeff Kirsher 433adfc5217SJeff Kirsher if (!mp->put(mp, 1)) 434adfc5217SJeff Kirsher return false; 435adfc5217SJeff Kirsher 436adfc5217SJeff Kirsher if (!vp->put(vp, 1)) { 437adfc5217SJeff Kirsher mp->get(mp, 1); 438adfc5217SJeff Kirsher return false; 439adfc5217SJeff Kirsher } 440adfc5217SJeff Kirsher 441adfc5217SJeff Kirsher return true; 442adfc5217SJeff Kirsher } 443adfc5217SJeff Kirsher 444adfc5217SJeff Kirsher /* check_add() callbacks */ 445adfc5217SJeff Kirsher static int bnx2x_check_mac_add(struct bnx2x_vlan_mac_obj *o, 446adfc5217SJeff Kirsher union bnx2x_classification_ramrod_data *data) 447adfc5217SJeff Kirsher { 448adfc5217SJeff Kirsher struct bnx2x_vlan_mac_registry_elem *pos; 449adfc5217SJeff Kirsher 450adfc5217SJeff Kirsher if (!is_valid_ether_addr(data->mac.mac)) 451adfc5217SJeff Kirsher return -EINVAL; 452adfc5217SJeff Kirsher 453adfc5217SJeff Kirsher /* Check if a requested MAC already exists */ 454adfc5217SJeff Kirsher list_for_each_entry(pos, &o->head, link) 455adfc5217SJeff Kirsher if (!memcmp(data->mac.mac, pos->u.mac.mac, ETH_ALEN)) 456adfc5217SJeff Kirsher return -EEXIST; 457adfc5217SJeff Kirsher 458adfc5217SJeff Kirsher return 0; 459adfc5217SJeff Kirsher } 460adfc5217SJeff Kirsher 461adfc5217SJeff Kirsher static int bnx2x_check_vlan_add(struct bnx2x_vlan_mac_obj *o, 462adfc5217SJeff Kirsher union bnx2x_classification_ramrod_data *data) 463adfc5217SJeff Kirsher { 464adfc5217SJeff Kirsher struct bnx2x_vlan_mac_registry_elem *pos; 465adfc5217SJeff Kirsher 466adfc5217SJeff Kirsher list_for_each_entry(pos, &o->head, link) 467adfc5217SJeff Kirsher if (data->vlan.vlan == pos->u.vlan.vlan) 468adfc5217SJeff Kirsher return -EEXIST; 469adfc5217SJeff Kirsher 470adfc5217SJeff Kirsher return 0; 471adfc5217SJeff Kirsher } 472adfc5217SJeff Kirsher 473adfc5217SJeff Kirsher static int bnx2x_check_vlan_mac_add(struct bnx2x_vlan_mac_obj *o, 474adfc5217SJeff Kirsher union bnx2x_classification_ramrod_data *data) 475adfc5217SJeff Kirsher { 476adfc5217SJeff Kirsher struct bnx2x_vlan_mac_registry_elem *pos; 477adfc5217SJeff Kirsher 478adfc5217SJeff Kirsher list_for_each_entry(pos, &o->head, link) 479adfc5217SJeff Kirsher if ((data->vlan_mac.vlan == pos->u.vlan_mac.vlan) && 480adfc5217SJeff Kirsher (!memcmp(data->vlan_mac.mac, pos->u.vlan_mac.mac, 481adfc5217SJeff Kirsher ETH_ALEN))) 482adfc5217SJeff Kirsher return -EEXIST; 483adfc5217SJeff Kirsher 484adfc5217SJeff Kirsher return 0; 485adfc5217SJeff Kirsher } 486adfc5217SJeff Kirsher 487adfc5217SJeff Kirsher 488adfc5217SJeff Kirsher /* check_del() callbacks */ 489adfc5217SJeff Kirsher static struct bnx2x_vlan_mac_registry_elem * 490adfc5217SJeff Kirsher bnx2x_check_mac_del(struct bnx2x_vlan_mac_obj *o, 491adfc5217SJeff Kirsher union bnx2x_classification_ramrod_data *data) 492adfc5217SJeff Kirsher { 493adfc5217SJeff Kirsher struct bnx2x_vlan_mac_registry_elem *pos; 494adfc5217SJeff Kirsher 495adfc5217SJeff Kirsher list_for_each_entry(pos, &o->head, link) 496adfc5217SJeff Kirsher if (!memcmp(data->mac.mac, pos->u.mac.mac, ETH_ALEN)) 497adfc5217SJeff Kirsher return pos; 498adfc5217SJeff Kirsher 499adfc5217SJeff Kirsher return NULL; 500adfc5217SJeff Kirsher } 501adfc5217SJeff Kirsher 502adfc5217SJeff Kirsher static struct bnx2x_vlan_mac_registry_elem * 503adfc5217SJeff Kirsher bnx2x_check_vlan_del(struct bnx2x_vlan_mac_obj *o, 504adfc5217SJeff Kirsher union bnx2x_classification_ramrod_data *data) 505adfc5217SJeff Kirsher { 506adfc5217SJeff Kirsher struct bnx2x_vlan_mac_registry_elem *pos; 507adfc5217SJeff Kirsher 508adfc5217SJeff Kirsher list_for_each_entry(pos, &o->head, link) 509adfc5217SJeff Kirsher if (data->vlan.vlan == pos->u.vlan.vlan) 510adfc5217SJeff Kirsher return pos; 511adfc5217SJeff Kirsher 512adfc5217SJeff Kirsher return NULL; 513adfc5217SJeff Kirsher } 514adfc5217SJeff Kirsher 515adfc5217SJeff Kirsher static struct bnx2x_vlan_mac_registry_elem * 516adfc5217SJeff Kirsher bnx2x_check_vlan_mac_del(struct bnx2x_vlan_mac_obj *o, 517adfc5217SJeff Kirsher union bnx2x_classification_ramrod_data *data) 518adfc5217SJeff Kirsher { 519adfc5217SJeff Kirsher struct bnx2x_vlan_mac_registry_elem *pos; 520adfc5217SJeff Kirsher 521adfc5217SJeff Kirsher list_for_each_entry(pos, &o->head, link) 522adfc5217SJeff Kirsher if ((data->vlan_mac.vlan == pos->u.vlan_mac.vlan) && 523adfc5217SJeff Kirsher (!memcmp(data->vlan_mac.mac, pos->u.vlan_mac.mac, 524adfc5217SJeff Kirsher ETH_ALEN))) 525adfc5217SJeff Kirsher return pos; 526adfc5217SJeff Kirsher 527adfc5217SJeff Kirsher return NULL; 528adfc5217SJeff Kirsher } 529adfc5217SJeff Kirsher 530adfc5217SJeff Kirsher /* check_move() callback */ 531adfc5217SJeff Kirsher static bool bnx2x_check_move(struct bnx2x_vlan_mac_obj *src_o, 532adfc5217SJeff Kirsher struct bnx2x_vlan_mac_obj *dst_o, 533adfc5217SJeff Kirsher union bnx2x_classification_ramrod_data *data) 534adfc5217SJeff Kirsher { 535adfc5217SJeff Kirsher struct bnx2x_vlan_mac_registry_elem *pos; 536adfc5217SJeff Kirsher int rc; 537adfc5217SJeff Kirsher 538adfc5217SJeff Kirsher /* Check if we can delete the requested configuration from the first 539adfc5217SJeff Kirsher * object. 540adfc5217SJeff Kirsher */ 541adfc5217SJeff Kirsher pos = src_o->check_del(src_o, data); 542adfc5217SJeff Kirsher 543adfc5217SJeff Kirsher /* check if configuration can be added */ 544adfc5217SJeff Kirsher rc = dst_o->check_add(dst_o, data); 545adfc5217SJeff Kirsher 546adfc5217SJeff Kirsher /* If this classification can not be added (is already set) 547adfc5217SJeff Kirsher * or can't be deleted - return an error. 548adfc5217SJeff Kirsher */ 549adfc5217SJeff Kirsher if (rc || !pos) 550adfc5217SJeff Kirsher return false; 551adfc5217SJeff Kirsher 552adfc5217SJeff Kirsher return true; 553adfc5217SJeff Kirsher } 554adfc5217SJeff Kirsher 555adfc5217SJeff Kirsher static bool bnx2x_check_move_always_err( 556adfc5217SJeff Kirsher struct bnx2x_vlan_mac_obj *src_o, 557adfc5217SJeff Kirsher struct bnx2x_vlan_mac_obj *dst_o, 558adfc5217SJeff Kirsher union bnx2x_classification_ramrod_data *data) 559adfc5217SJeff Kirsher { 560adfc5217SJeff Kirsher return false; 561adfc5217SJeff Kirsher } 562adfc5217SJeff Kirsher 563adfc5217SJeff Kirsher 564adfc5217SJeff Kirsher static inline u8 bnx2x_vlan_mac_get_rx_tx_flag(struct bnx2x_vlan_mac_obj *o) 565adfc5217SJeff Kirsher { 566adfc5217SJeff Kirsher struct bnx2x_raw_obj *raw = &o->raw; 567adfc5217SJeff Kirsher u8 rx_tx_flag = 0; 568adfc5217SJeff Kirsher 569adfc5217SJeff Kirsher if ((raw->obj_type == BNX2X_OBJ_TYPE_TX) || 570adfc5217SJeff Kirsher (raw->obj_type == BNX2X_OBJ_TYPE_RX_TX)) 571adfc5217SJeff Kirsher rx_tx_flag |= ETH_CLASSIFY_CMD_HEADER_TX_CMD; 572adfc5217SJeff Kirsher 573adfc5217SJeff Kirsher if ((raw->obj_type == BNX2X_OBJ_TYPE_RX) || 574adfc5217SJeff Kirsher (raw->obj_type == BNX2X_OBJ_TYPE_RX_TX)) 575adfc5217SJeff Kirsher rx_tx_flag |= ETH_CLASSIFY_CMD_HEADER_RX_CMD; 576adfc5217SJeff Kirsher 577adfc5217SJeff Kirsher return rx_tx_flag; 578adfc5217SJeff Kirsher } 579adfc5217SJeff Kirsher 580adfc5217SJeff Kirsher /* LLH CAM line allocations */ 581adfc5217SJeff Kirsher enum { 582adfc5217SJeff Kirsher LLH_CAM_ISCSI_ETH_LINE = 0, 583adfc5217SJeff Kirsher LLH_CAM_ETH_LINE, 584adfc5217SJeff Kirsher LLH_CAM_MAX_PF_LINE = NIG_REG_LLH1_FUNC_MEM_SIZE / 2 585adfc5217SJeff Kirsher }; 586adfc5217SJeff Kirsher 587adfc5217SJeff Kirsher static inline void bnx2x_set_mac_in_nig(struct bnx2x *bp, 588adfc5217SJeff Kirsher bool add, unsigned char *dev_addr, int index) 589adfc5217SJeff Kirsher { 590adfc5217SJeff Kirsher u32 wb_data[2]; 591adfc5217SJeff Kirsher u32 reg_offset = BP_PORT(bp) ? NIG_REG_LLH1_FUNC_MEM : 592adfc5217SJeff Kirsher NIG_REG_LLH0_FUNC_MEM; 593adfc5217SJeff Kirsher 594adfc5217SJeff Kirsher if (!IS_MF_SI(bp) || index > LLH_CAM_MAX_PF_LINE) 595adfc5217SJeff Kirsher return; 596adfc5217SJeff Kirsher 597adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "Going to %s LLH configuration at entry %d\n", 598adfc5217SJeff Kirsher (add ? "ADD" : "DELETE"), index); 599adfc5217SJeff Kirsher 600adfc5217SJeff Kirsher if (add) { 601adfc5217SJeff Kirsher /* LLH_FUNC_MEM is a u64 WB register */ 602adfc5217SJeff Kirsher reg_offset += 8*index; 603adfc5217SJeff Kirsher 604adfc5217SJeff Kirsher wb_data[0] = ((dev_addr[2] << 24) | (dev_addr[3] << 16) | 605adfc5217SJeff Kirsher (dev_addr[4] << 8) | dev_addr[5]); 606adfc5217SJeff Kirsher wb_data[1] = ((dev_addr[0] << 8) | dev_addr[1]); 607adfc5217SJeff Kirsher 608adfc5217SJeff Kirsher REG_WR_DMAE(bp, reg_offset, wb_data, 2); 609adfc5217SJeff Kirsher } 610adfc5217SJeff Kirsher 611adfc5217SJeff Kirsher REG_WR(bp, (BP_PORT(bp) ? NIG_REG_LLH1_FUNC_MEM_ENABLE : 612adfc5217SJeff Kirsher NIG_REG_LLH0_FUNC_MEM_ENABLE) + 4*index, add); 613adfc5217SJeff Kirsher } 614adfc5217SJeff Kirsher 615adfc5217SJeff Kirsher /** 616adfc5217SJeff Kirsher * bnx2x_vlan_mac_set_cmd_hdr_e2 - set a header in a single classify ramrod 617adfc5217SJeff Kirsher * 618adfc5217SJeff Kirsher * @bp: device handle 619adfc5217SJeff Kirsher * @o: queue for which we want to configure this rule 620adfc5217SJeff Kirsher * @add: if true the command is an ADD command, DEL otherwise 621adfc5217SJeff Kirsher * @opcode: CLASSIFY_RULE_OPCODE_XXX 622adfc5217SJeff Kirsher * @hdr: pointer to a header to setup 623adfc5217SJeff Kirsher * 624adfc5217SJeff Kirsher */ 625adfc5217SJeff Kirsher static inline void bnx2x_vlan_mac_set_cmd_hdr_e2(struct bnx2x *bp, 626adfc5217SJeff Kirsher struct bnx2x_vlan_mac_obj *o, bool add, int opcode, 627adfc5217SJeff Kirsher struct eth_classify_cmd_header *hdr) 628adfc5217SJeff Kirsher { 629adfc5217SJeff Kirsher struct bnx2x_raw_obj *raw = &o->raw; 630adfc5217SJeff Kirsher 631adfc5217SJeff Kirsher hdr->client_id = raw->cl_id; 632adfc5217SJeff Kirsher hdr->func_id = raw->func_id; 633adfc5217SJeff Kirsher 634adfc5217SJeff Kirsher /* Rx or/and Tx (internal switching) configuration ? */ 635adfc5217SJeff Kirsher hdr->cmd_general_data |= 636adfc5217SJeff Kirsher bnx2x_vlan_mac_get_rx_tx_flag(o); 637adfc5217SJeff Kirsher 638adfc5217SJeff Kirsher if (add) 639adfc5217SJeff Kirsher hdr->cmd_general_data |= ETH_CLASSIFY_CMD_HEADER_IS_ADD; 640adfc5217SJeff Kirsher 641adfc5217SJeff Kirsher hdr->cmd_general_data |= 642adfc5217SJeff Kirsher (opcode << ETH_CLASSIFY_CMD_HEADER_OPCODE_SHIFT); 643adfc5217SJeff Kirsher } 644adfc5217SJeff Kirsher 645adfc5217SJeff Kirsher /** 646adfc5217SJeff Kirsher * bnx2x_vlan_mac_set_rdata_hdr_e2 - set the classify ramrod data header 647adfc5217SJeff Kirsher * 648adfc5217SJeff Kirsher * @cid: connection id 649adfc5217SJeff Kirsher * @type: BNX2X_FILTER_XXX_PENDING 650adfc5217SJeff Kirsher * @hdr: poiter to header to setup 651adfc5217SJeff Kirsher * @rule_cnt: 652adfc5217SJeff Kirsher * 653adfc5217SJeff Kirsher * currently we always configure one rule and echo field to contain a CID and an 654adfc5217SJeff Kirsher * opcode type. 655adfc5217SJeff Kirsher */ 656adfc5217SJeff Kirsher static inline void bnx2x_vlan_mac_set_rdata_hdr_e2(u32 cid, int type, 657adfc5217SJeff Kirsher struct eth_classify_header *hdr, int rule_cnt) 658adfc5217SJeff Kirsher { 659adfc5217SJeff Kirsher hdr->echo = (cid & BNX2X_SWCID_MASK) | (type << BNX2X_SWCID_SHIFT); 660adfc5217SJeff Kirsher hdr->rule_cnt = (u8)rule_cnt; 661adfc5217SJeff Kirsher } 662adfc5217SJeff Kirsher 663adfc5217SJeff Kirsher 664adfc5217SJeff Kirsher /* hw_config() callbacks */ 665adfc5217SJeff Kirsher static void bnx2x_set_one_mac_e2(struct bnx2x *bp, 666adfc5217SJeff Kirsher struct bnx2x_vlan_mac_obj *o, 667adfc5217SJeff Kirsher struct bnx2x_exeq_elem *elem, int rule_idx, 668adfc5217SJeff Kirsher int cam_offset) 669adfc5217SJeff Kirsher { 670adfc5217SJeff Kirsher struct bnx2x_raw_obj *raw = &o->raw; 671adfc5217SJeff Kirsher struct eth_classify_rules_ramrod_data *data = 672adfc5217SJeff Kirsher (struct eth_classify_rules_ramrod_data *)(raw->rdata); 673adfc5217SJeff Kirsher int rule_cnt = rule_idx + 1, cmd = elem->cmd_data.vlan_mac.cmd; 674adfc5217SJeff Kirsher union eth_classify_rule_cmd *rule_entry = &data->rules[rule_idx]; 675adfc5217SJeff Kirsher bool add = (cmd == BNX2X_VLAN_MAC_ADD) ? true : false; 676adfc5217SJeff Kirsher unsigned long *vlan_mac_flags = &elem->cmd_data.vlan_mac.vlan_mac_flags; 677adfc5217SJeff Kirsher u8 *mac = elem->cmd_data.vlan_mac.u.mac.mac; 678adfc5217SJeff Kirsher 679adfc5217SJeff Kirsher /* 680adfc5217SJeff Kirsher * Set LLH CAM entry: currently only iSCSI and ETH macs are 681adfc5217SJeff Kirsher * relevant. In addition, current implementation is tuned for a 682adfc5217SJeff Kirsher * single ETH MAC. 683adfc5217SJeff Kirsher * 684adfc5217SJeff Kirsher * When multiple unicast ETH MACs PF configuration in switch 685adfc5217SJeff Kirsher * independent mode is required (NetQ, multiple netdev MACs, 686adfc5217SJeff Kirsher * etc.), consider better utilisation of 8 per function MAC 687adfc5217SJeff Kirsher * entries in the LLH register. There is also 688adfc5217SJeff Kirsher * NIG_REG_P[01]_LLH_FUNC_MEM2 registers that complete the 689adfc5217SJeff Kirsher * total number of CAM entries to 16. 690adfc5217SJeff Kirsher * 691adfc5217SJeff Kirsher * Currently we won't configure NIG for MACs other than a primary ETH 692adfc5217SJeff Kirsher * MAC and iSCSI L2 MAC. 693adfc5217SJeff Kirsher * 694adfc5217SJeff Kirsher * If this MAC is moving from one Queue to another, no need to change 695adfc5217SJeff Kirsher * NIG configuration. 696adfc5217SJeff Kirsher */ 697adfc5217SJeff Kirsher if (cmd != BNX2X_VLAN_MAC_MOVE) { 698adfc5217SJeff Kirsher if (test_bit(BNX2X_ISCSI_ETH_MAC, vlan_mac_flags)) 699adfc5217SJeff Kirsher bnx2x_set_mac_in_nig(bp, add, mac, 700adfc5217SJeff Kirsher LLH_CAM_ISCSI_ETH_LINE); 701adfc5217SJeff Kirsher else if (test_bit(BNX2X_ETH_MAC, vlan_mac_flags)) 702adfc5217SJeff Kirsher bnx2x_set_mac_in_nig(bp, add, mac, LLH_CAM_ETH_LINE); 703adfc5217SJeff Kirsher } 704adfc5217SJeff Kirsher 705adfc5217SJeff Kirsher /* Reset the ramrod data buffer for the first rule */ 706adfc5217SJeff Kirsher if (rule_idx == 0) 707adfc5217SJeff Kirsher memset(data, 0, sizeof(*data)); 708adfc5217SJeff Kirsher 709adfc5217SJeff Kirsher /* Setup a command header */ 710adfc5217SJeff Kirsher bnx2x_vlan_mac_set_cmd_hdr_e2(bp, o, add, CLASSIFY_RULE_OPCODE_MAC, 711adfc5217SJeff Kirsher &rule_entry->mac.header); 712adfc5217SJeff Kirsher 7130f9dad10SJoe Perches DP(BNX2X_MSG_SP, "About to %s MAC %pM for Queue %d\n", 7140f9dad10SJoe Perches add ? "add" : "delete", mac, raw->cl_id); 715adfc5217SJeff Kirsher 716adfc5217SJeff Kirsher /* Set a MAC itself */ 717adfc5217SJeff Kirsher bnx2x_set_fw_mac_addr(&rule_entry->mac.mac_msb, 718adfc5217SJeff Kirsher &rule_entry->mac.mac_mid, 719adfc5217SJeff Kirsher &rule_entry->mac.mac_lsb, mac); 720adfc5217SJeff Kirsher 721adfc5217SJeff Kirsher /* MOVE: Add a rule that will add this MAC to the target Queue */ 722adfc5217SJeff Kirsher if (cmd == BNX2X_VLAN_MAC_MOVE) { 723adfc5217SJeff Kirsher rule_entry++; 724adfc5217SJeff Kirsher rule_cnt++; 725adfc5217SJeff Kirsher 726adfc5217SJeff Kirsher /* Setup ramrod data */ 727adfc5217SJeff Kirsher bnx2x_vlan_mac_set_cmd_hdr_e2(bp, 728adfc5217SJeff Kirsher elem->cmd_data.vlan_mac.target_obj, 729adfc5217SJeff Kirsher true, CLASSIFY_RULE_OPCODE_MAC, 730adfc5217SJeff Kirsher &rule_entry->mac.header); 731adfc5217SJeff Kirsher 732adfc5217SJeff Kirsher /* Set a MAC itself */ 733adfc5217SJeff Kirsher bnx2x_set_fw_mac_addr(&rule_entry->mac.mac_msb, 734adfc5217SJeff Kirsher &rule_entry->mac.mac_mid, 735adfc5217SJeff Kirsher &rule_entry->mac.mac_lsb, mac); 736adfc5217SJeff Kirsher } 737adfc5217SJeff Kirsher 738adfc5217SJeff Kirsher /* Set the ramrod data header */ 739adfc5217SJeff Kirsher /* TODO: take this to the higher level in order to prevent multiple 740adfc5217SJeff Kirsher writing */ 741adfc5217SJeff Kirsher bnx2x_vlan_mac_set_rdata_hdr_e2(raw->cid, raw->state, &data->header, 742adfc5217SJeff Kirsher rule_cnt); 743adfc5217SJeff Kirsher } 744adfc5217SJeff Kirsher 745adfc5217SJeff Kirsher /** 746adfc5217SJeff Kirsher * bnx2x_vlan_mac_set_rdata_hdr_e1x - set a header in a single classify ramrod 747adfc5217SJeff Kirsher * 748adfc5217SJeff Kirsher * @bp: device handle 749adfc5217SJeff Kirsher * @o: queue 750adfc5217SJeff Kirsher * @type: 751adfc5217SJeff Kirsher * @cam_offset: offset in cam memory 752adfc5217SJeff Kirsher * @hdr: pointer to a header to setup 753adfc5217SJeff Kirsher * 754adfc5217SJeff Kirsher * E1/E1H 755adfc5217SJeff Kirsher */ 756adfc5217SJeff Kirsher static inline void bnx2x_vlan_mac_set_rdata_hdr_e1x(struct bnx2x *bp, 757adfc5217SJeff Kirsher struct bnx2x_vlan_mac_obj *o, int type, int cam_offset, 758adfc5217SJeff Kirsher struct mac_configuration_hdr *hdr) 759adfc5217SJeff Kirsher { 760adfc5217SJeff Kirsher struct bnx2x_raw_obj *r = &o->raw; 761adfc5217SJeff Kirsher 762adfc5217SJeff Kirsher hdr->length = 1; 763adfc5217SJeff Kirsher hdr->offset = (u8)cam_offset; 764adfc5217SJeff Kirsher hdr->client_id = 0xff; 765adfc5217SJeff Kirsher hdr->echo = ((r->cid & BNX2X_SWCID_MASK) | (type << BNX2X_SWCID_SHIFT)); 766adfc5217SJeff Kirsher } 767adfc5217SJeff Kirsher 768adfc5217SJeff Kirsher static inline void bnx2x_vlan_mac_set_cfg_entry_e1x(struct bnx2x *bp, 769adfc5217SJeff Kirsher struct bnx2x_vlan_mac_obj *o, bool add, int opcode, u8 *mac, 770adfc5217SJeff Kirsher u16 vlan_id, struct mac_configuration_entry *cfg_entry) 771adfc5217SJeff Kirsher { 772adfc5217SJeff Kirsher struct bnx2x_raw_obj *r = &o->raw; 773adfc5217SJeff Kirsher u32 cl_bit_vec = (1 << r->cl_id); 774adfc5217SJeff Kirsher 775adfc5217SJeff Kirsher cfg_entry->clients_bit_vector = cpu_to_le32(cl_bit_vec); 776adfc5217SJeff Kirsher cfg_entry->pf_id = r->func_id; 777adfc5217SJeff Kirsher cfg_entry->vlan_id = cpu_to_le16(vlan_id); 778adfc5217SJeff Kirsher 779adfc5217SJeff Kirsher if (add) { 780adfc5217SJeff Kirsher SET_FLAG(cfg_entry->flags, MAC_CONFIGURATION_ENTRY_ACTION_TYPE, 781adfc5217SJeff Kirsher T_ETH_MAC_COMMAND_SET); 782adfc5217SJeff Kirsher SET_FLAG(cfg_entry->flags, 783adfc5217SJeff Kirsher MAC_CONFIGURATION_ENTRY_VLAN_FILTERING_MODE, opcode); 784adfc5217SJeff Kirsher 785adfc5217SJeff Kirsher /* Set a MAC in a ramrod data */ 786adfc5217SJeff Kirsher bnx2x_set_fw_mac_addr(&cfg_entry->msb_mac_addr, 787adfc5217SJeff Kirsher &cfg_entry->middle_mac_addr, 788adfc5217SJeff Kirsher &cfg_entry->lsb_mac_addr, mac); 789adfc5217SJeff Kirsher } else 790adfc5217SJeff Kirsher SET_FLAG(cfg_entry->flags, MAC_CONFIGURATION_ENTRY_ACTION_TYPE, 791adfc5217SJeff Kirsher T_ETH_MAC_COMMAND_INVALIDATE); 792adfc5217SJeff Kirsher } 793adfc5217SJeff Kirsher 794adfc5217SJeff Kirsher static inline void bnx2x_vlan_mac_set_rdata_e1x(struct bnx2x *bp, 795adfc5217SJeff Kirsher struct bnx2x_vlan_mac_obj *o, int type, int cam_offset, bool add, 796adfc5217SJeff Kirsher u8 *mac, u16 vlan_id, int opcode, struct mac_configuration_cmd *config) 797adfc5217SJeff Kirsher { 798adfc5217SJeff Kirsher struct mac_configuration_entry *cfg_entry = &config->config_table[0]; 799adfc5217SJeff Kirsher struct bnx2x_raw_obj *raw = &o->raw; 800adfc5217SJeff Kirsher 801adfc5217SJeff Kirsher bnx2x_vlan_mac_set_rdata_hdr_e1x(bp, o, type, cam_offset, 802adfc5217SJeff Kirsher &config->hdr); 803adfc5217SJeff Kirsher bnx2x_vlan_mac_set_cfg_entry_e1x(bp, o, add, opcode, mac, vlan_id, 804adfc5217SJeff Kirsher cfg_entry); 805adfc5217SJeff Kirsher 8060f9dad10SJoe Perches DP(BNX2X_MSG_SP, "%s MAC %pM CLID %d CAM offset %d\n", 8070f9dad10SJoe Perches add ? "setting" : "clearing", 8080f9dad10SJoe Perches mac, raw->cl_id, cam_offset); 809adfc5217SJeff Kirsher } 810adfc5217SJeff Kirsher 811adfc5217SJeff Kirsher /** 812adfc5217SJeff Kirsher * bnx2x_set_one_mac_e1x - fill a single MAC rule ramrod data 813adfc5217SJeff Kirsher * 814adfc5217SJeff Kirsher * @bp: device handle 815adfc5217SJeff Kirsher * @o: bnx2x_vlan_mac_obj 816adfc5217SJeff Kirsher * @elem: bnx2x_exeq_elem 817adfc5217SJeff Kirsher * @rule_idx: rule_idx 818adfc5217SJeff Kirsher * @cam_offset: cam_offset 819adfc5217SJeff Kirsher */ 820adfc5217SJeff Kirsher static void bnx2x_set_one_mac_e1x(struct bnx2x *bp, 821adfc5217SJeff Kirsher struct bnx2x_vlan_mac_obj *o, 822adfc5217SJeff Kirsher struct bnx2x_exeq_elem *elem, int rule_idx, 823adfc5217SJeff Kirsher int cam_offset) 824adfc5217SJeff Kirsher { 825adfc5217SJeff Kirsher struct bnx2x_raw_obj *raw = &o->raw; 826adfc5217SJeff Kirsher struct mac_configuration_cmd *config = 827adfc5217SJeff Kirsher (struct mac_configuration_cmd *)(raw->rdata); 828adfc5217SJeff Kirsher /* 829adfc5217SJeff Kirsher * 57710 and 57711 do not support MOVE command, 830adfc5217SJeff Kirsher * so it's either ADD or DEL 831adfc5217SJeff Kirsher */ 832adfc5217SJeff Kirsher bool add = (elem->cmd_data.vlan_mac.cmd == BNX2X_VLAN_MAC_ADD) ? 833adfc5217SJeff Kirsher true : false; 834adfc5217SJeff Kirsher 835adfc5217SJeff Kirsher /* Reset the ramrod data buffer */ 836adfc5217SJeff Kirsher memset(config, 0, sizeof(*config)); 837adfc5217SJeff Kirsher 838adfc5217SJeff Kirsher bnx2x_vlan_mac_set_rdata_e1x(bp, o, BNX2X_FILTER_MAC_PENDING, 839adfc5217SJeff Kirsher cam_offset, add, 840adfc5217SJeff Kirsher elem->cmd_data.vlan_mac.u.mac.mac, 0, 841adfc5217SJeff Kirsher ETH_VLAN_FILTER_ANY_VLAN, config); 842adfc5217SJeff Kirsher } 843adfc5217SJeff Kirsher 844adfc5217SJeff Kirsher static void bnx2x_set_one_vlan_e2(struct bnx2x *bp, 845adfc5217SJeff Kirsher struct bnx2x_vlan_mac_obj *o, 846adfc5217SJeff Kirsher struct bnx2x_exeq_elem *elem, int rule_idx, 847adfc5217SJeff Kirsher int cam_offset) 848adfc5217SJeff Kirsher { 849adfc5217SJeff Kirsher struct bnx2x_raw_obj *raw = &o->raw; 850adfc5217SJeff Kirsher struct eth_classify_rules_ramrod_data *data = 851adfc5217SJeff Kirsher (struct eth_classify_rules_ramrod_data *)(raw->rdata); 852adfc5217SJeff Kirsher int rule_cnt = rule_idx + 1; 853adfc5217SJeff Kirsher union eth_classify_rule_cmd *rule_entry = &data->rules[rule_idx]; 854adfc5217SJeff Kirsher int cmd = elem->cmd_data.vlan_mac.cmd; 855adfc5217SJeff Kirsher bool add = (cmd == BNX2X_VLAN_MAC_ADD) ? true : false; 856adfc5217SJeff Kirsher u16 vlan = elem->cmd_data.vlan_mac.u.vlan.vlan; 857adfc5217SJeff Kirsher 858adfc5217SJeff Kirsher /* Reset the ramrod data buffer for the first rule */ 859adfc5217SJeff Kirsher if (rule_idx == 0) 860adfc5217SJeff Kirsher memset(data, 0, sizeof(*data)); 861adfc5217SJeff Kirsher 862adfc5217SJeff Kirsher /* Set a rule header */ 863adfc5217SJeff Kirsher bnx2x_vlan_mac_set_cmd_hdr_e2(bp, o, add, CLASSIFY_RULE_OPCODE_VLAN, 864adfc5217SJeff Kirsher &rule_entry->vlan.header); 865adfc5217SJeff Kirsher 866adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "About to %s VLAN %d\n", (add ? "add" : "delete"), 867adfc5217SJeff Kirsher vlan); 868adfc5217SJeff Kirsher 869adfc5217SJeff Kirsher /* Set a VLAN itself */ 870adfc5217SJeff Kirsher rule_entry->vlan.vlan = cpu_to_le16(vlan); 871adfc5217SJeff Kirsher 872adfc5217SJeff Kirsher /* MOVE: Add a rule that will add this MAC to the target Queue */ 873adfc5217SJeff Kirsher if (cmd == BNX2X_VLAN_MAC_MOVE) { 874adfc5217SJeff Kirsher rule_entry++; 875adfc5217SJeff Kirsher rule_cnt++; 876adfc5217SJeff Kirsher 877adfc5217SJeff Kirsher /* Setup ramrod data */ 878adfc5217SJeff Kirsher bnx2x_vlan_mac_set_cmd_hdr_e2(bp, 879adfc5217SJeff Kirsher elem->cmd_data.vlan_mac.target_obj, 880adfc5217SJeff Kirsher true, CLASSIFY_RULE_OPCODE_VLAN, 881adfc5217SJeff Kirsher &rule_entry->vlan.header); 882adfc5217SJeff Kirsher 883adfc5217SJeff Kirsher /* Set a VLAN itself */ 884adfc5217SJeff Kirsher rule_entry->vlan.vlan = cpu_to_le16(vlan); 885adfc5217SJeff Kirsher } 886adfc5217SJeff Kirsher 887adfc5217SJeff Kirsher /* Set the ramrod data header */ 888adfc5217SJeff Kirsher /* TODO: take this to the higher level in order to prevent multiple 889adfc5217SJeff Kirsher writing */ 890adfc5217SJeff Kirsher bnx2x_vlan_mac_set_rdata_hdr_e2(raw->cid, raw->state, &data->header, 891adfc5217SJeff Kirsher rule_cnt); 892adfc5217SJeff Kirsher } 893adfc5217SJeff Kirsher 894adfc5217SJeff Kirsher static void bnx2x_set_one_vlan_mac_e2(struct bnx2x *bp, 895adfc5217SJeff Kirsher struct bnx2x_vlan_mac_obj *o, 896adfc5217SJeff Kirsher struct bnx2x_exeq_elem *elem, 897adfc5217SJeff Kirsher int rule_idx, int cam_offset) 898adfc5217SJeff Kirsher { 899adfc5217SJeff Kirsher struct bnx2x_raw_obj *raw = &o->raw; 900adfc5217SJeff Kirsher struct eth_classify_rules_ramrod_data *data = 901adfc5217SJeff Kirsher (struct eth_classify_rules_ramrod_data *)(raw->rdata); 902adfc5217SJeff Kirsher int rule_cnt = rule_idx + 1; 903adfc5217SJeff Kirsher union eth_classify_rule_cmd *rule_entry = &data->rules[rule_idx]; 904adfc5217SJeff Kirsher int cmd = elem->cmd_data.vlan_mac.cmd; 905adfc5217SJeff Kirsher bool add = (cmd == BNX2X_VLAN_MAC_ADD) ? true : false; 906adfc5217SJeff Kirsher u16 vlan = elem->cmd_data.vlan_mac.u.vlan_mac.vlan; 907adfc5217SJeff Kirsher u8 *mac = elem->cmd_data.vlan_mac.u.vlan_mac.mac; 908adfc5217SJeff Kirsher 909adfc5217SJeff Kirsher 910adfc5217SJeff Kirsher /* Reset the ramrod data buffer for the first rule */ 911adfc5217SJeff Kirsher if (rule_idx == 0) 912adfc5217SJeff Kirsher memset(data, 0, sizeof(*data)); 913adfc5217SJeff Kirsher 914adfc5217SJeff Kirsher /* Set a rule header */ 915adfc5217SJeff Kirsher bnx2x_vlan_mac_set_cmd_hdr_e2(bp, o, add, CLASSIFY_RULE_OPCODE_PAIR, 916adfc5217SJeff Kirsher &rule_entry->pair.header); 917adfc5217SJeff Kirsher 918adfc5217SJeff Kirsher /* Set VLAN and MAC themselvs */ 919adfc5217SJeff Kirsher rule_entry->pair.vlan = cpu_to_le16(vlan); 920adfc5217SJeff Kirsher bnx2x_set_fw_mac_addr(&rule_entry->pair.mac_msb, 921adfc5217SJeff Kirsher &rule_entry->pair.mac_mid, 922adfc5217SJeff Kirsher &rule_entry->pair.mac_lsb, mac); 923adfc5217SJeff Kirsher 924adfc5217SJeff Kirsher /* MOVE: Add a rule that will add this MAC to the target Queue */ 925adfc5217SJeff Kirsher if (cmd == BNX2X_VLAN_MAC_MOVE) { 926adfc5217SJeff Kirsher rule_entry++; 927adfc5217SJeff Kirsher rule_cnt++; 928adfc5217SJeff Kirsher 929adfc5217SJeff Kirsher /* Setup ramrod data */ 930adfc5217SJeff Kirsher bnx2x_vlan_mac_set_cmd_hdr_e2(bp, 931adfc5217SJeff Kirsher elem->cmd_data.vlan_mac.target_obj, 932adfc5217SJeff Kirsher true, CLASSIFY_RULE_OPCODE_PAIR, 933adfc5217SJeff Kirsher &rule_entry->pair.header); 934adfc5217SJeff Kirsher 935adfc5217SJeff Kirsher /* Set a VLAN itself */ 936adfc5217SJeff Kirsher rule_entry->pair.vlan = cpu_to_le16(vlan); 937adfc5217SJeff Kirsher bnx2x_set_fw_mac_addr(&rule_entry->pair.mac_msb, 938adfc5217SJeff Kirsher &rule_entry->pair.mac_mid, 939adfc5217SJeff Kirsher &rule_entry->pair.mac_lsb, mac); 940adfc5217SJeff Kirsher } 941adfc5217SJeff Kirsher 942adfc5217SJeff Kirsher /* Set the ramrod data header */ 943adfc5217SJeff Kirsher /* TODO: take this to the higher level in order to prevent multiple 944adfc5217SJeff Kirsher writing */ 945adfc5217SJeff Kirsher bnx2x_vlan_mac_set_rdata_hdr_e2(raw->cid, raw->state, &data->header, 946adfc5217SJeff Kirsher rule_cnt); 947adfc5217SJeff Kirsher } 948adfc5217SJeff Kirsher 949adfc5217SJeff Kirsher /** 950adfc5217SJeff Kirsher * bnx2x_set_one_vlan_mac_e1h - 951adfc5217SJeff Kirsher * 952adfc5217SJeff Kirsher * @bp: device handle 953adfc5217SJeff Kirsher * @o: bnx2x_vlan_mac_obj 954adfc5217SJeff Kirsher * @elem: bnx2x_exeq_elem 955adfc5217SJeff Kirsher * @rule_idx: rule_idx 956adfc5217SJeff Kirsher * @cam_offset: cam_offset 957adfc5217SJeff Kirsher */ 958adfc5217SJeff Kirsher static void bnx2x_set_one_vlan_mac_e1h(struct bnx2x *bp, 959adfc5217SJeff Kirsher struct bnx2x_vlan_mac_obj *o, 960adfc5217SJeff Kirsher struct bnx2x_exeq_elem *elem, 961adfc5217SJeff Kirsher int rule_idx, int cam_offset) 962adfc5217SJeff Kirsher { 963adfc5217SJeff Kirsher struct bnx2x_raw_obj *raw = &o->raw; 964adfc5217SJeff Kirsher struct mac_configuration_cmd *config = 965adfc5217SJeff Kirsher (struct mac_configuration_cmd *)(raw->rdata); 966adfc5217SJeff Kirsher /* 967adfc5217SJeff Kirsher * 57710 and 57711 do not support MOVE command, 968adfc5217SJeff Kirsher * so it's either ADD or DEL 969adfc5217SJeff Kirsher */ 970adfc5217SJeff Kirsher bool add = (elem->cmd_data.vlan_mac.cmd == BNX2X_VLAN_MAC_ADD) ? 971adfc5217SJeff Kirsher true : false; 972adfc5217SJeff Kirsher 973adfc5217SJeff Kirsher /* Reset the ramrod data buffer */ 974adfc5217SJeff Kirsher memset(config, 0, sizeof(*config)); 975adfc5217SJeff Kirsher 976adfc5217SJeff Kirsher bnx2x_vlan_mac_set_rdata_e1x(bp, o, BNX2X_FILTER_VLAN_MAC_PENDING, 977adfc5217SJeff Kirsher cam_offset, add, 978adfc5217SJeff Kirsher elem->cmd_data.vlan_mac.u.vlan_mac.mac, 979adfc5217SJeff Kirsher elem->cmd_data.vlan_mac.u.vlan_mac.vlan, 980adfc5217SJeff Kirsher ETH_VLAN_FILTER_CLASSIFY, config); 981adfc5217SJeff Kirsher } 982adfc5217SJeff Kirsher 983adfc5217SJeff Kirsher #define list_next_entry(pos, member) \ 984adfc5217SJeff Kirsher list_entry((pos)->member.next, typeof(*(pos)), member) 985adfc5217SJeff Kirsher 986adfc5217SJeff Kirsher /** 987adfc5217SJeff Kirsher * bnx2x_vlan_mac_restore - reconfigure next MAC/VLAN/VLAN-MAC element 988adfc5217SJeff Kirsher * 989adfc5217SJeff Kirsher * @bp: device handle 990adfc5217SJeff Kirsher * @p: command parameters 991adfc5217SJeff Kirsher * @ppos: pointer to the cooky 992adfc5217SJeff Kirsher * 993adfc5217SJeff Kirsher * reconfigure next MAC/VLAN/VLAN-MAC element from the 994adfc5217SJeff Kirsher * previously configured elements list. 995adfc5217SJeff Kirsher * 996adfc5217SJeff Kirsher * from command parameters only RAMROD_COMP_WAIT bit in ramrod_flags is taken 997adfc5217SJeff Kirsher * into an account 998adfc5217SJeff Kirsher * 999adfc5217SJeff Kirsher * pointer to the cooky - that should be given back in the next call to make 1000adfc5217SJeff Kirsher * function handle the next element. If *ppos is set to NULL it will restart the 1001adfc5217SJeff Kirsher * iterator. If returned *ppos == NULL this means that the last element has been 1002adfc5217SJeff Kirsher * handled. 1003adfc5217SJeff Kirsher * 1004adfc5217SJeff Kirsher */ 1005adfc5217SJeff Kirsher static int bnx2x_vlan_mac_restore(struct bnx2x *bp, 1006adfc5217SJeff Kirsher struct bnx2x_vlan_mac_ramrod_params *p, 1007adfc5217SJeff Kirsher struct bnx2x_vlan_mac_registry_elem **ppos) 1008adfc5217SJeff Kirsher { 1009adfc5217SJeff Kirsher struct bnx2x_vlan_mac_registry_elem *pos; 1010adfc5217SJeff Kirsher struct bnx2x_vlan_mac_obj *o = p->vlan_mac_obj; 1011adfc5217SJeff Kirsher 1012adfc5217SJeff Kirsher /* If list is empty - there is nothing to do here */ 1013adfc5217SJeff Kirsher if (list_empty(&o->head)) { 1014adfc5217SJeff Kirsher *ppos = NULL; 1015adfc5217SJeff Kirsher return 0; 1016adfc5217SJeff Kirsher } 1017adfc5217SJeff Kirsher 1018adfc5217SJeff Kirsher /* make a step... */ 1019adfc5217SJeff Kirsher if (*ppos == NULL) 1020adfc5217SJeff Kirsher *ppos = list_first_entry(&o->head, 1021adfc5217SJeff Kirsher struct bnx2x_vlan_mac_registry_elem, 1022adfc5217SJeff Kirsher link); 1023adfc5217SJeff Kirsher else 1024adfc5217SJeff Kirsher *ppos = list_next_entry(*ppos, link); 1025adfc5217SJeff Kirsher 1026adfc5217SJeff Kirsher pos = *ppos; 1027adfc5217SJeff Kirsher 1028adfc5217SJeff Kirsher /* If it's the last step - return NULL */ 1029adfc5217SJeff Kirsher if (list_is_last(&pos->link, &o->head)) 1030adfc5217SJeff Kirsher *ppos = NULL; 1031adfc5217SJeff Kirsher 1032adfc5217SJeff Kirsher /* Prepare a 'user_req' */ 1033adfc5217SJeff Kirsher memcpy(&p->user_req.u, &pos->u, sizeof(pos->u)); 1034adfc5217SJeff Kirsher 1035adfc5217SJeff Kirsher /* Set the command */ 1036adfc5217SJeff Kirsher p->user_req.cmd = BNX2X_VLAN_MAC_ADD; 1037adfc5217SJeff Kirsher 1038adfc5217SJeff Kirsher /* Set vlan_mac_flags */ 1039adfc5217SJeff Kirsher p->user_req.vlan_mac_flags = pos->vlan_mac_flags; 1040adfc5217SJeff Kirsher 1041adfc5217SJeff Kirsher /* Set a restore bit */ 1042adfc5217SJeff Kirsher __set_bit(RAMROD_RESTORE, &p->ramrod_flags); 1043adfc5217SJeff Kirsher 1044adfc5217SJeff Kirsher return bnx2x_config_vlan_mac(bp, p); 1045adfc5217SJeff Kirsher } 1046adfc5217SJeff Kirsher 1047adfc5217SJeff Kirsher /* 1048adfc5217SJeff Kirsher * bnx2x_exeq_get_mac/bnx2x_exeq_get_vlan/bnx2x_exeq_get_vlan_mac return a 1049adfc5217SJeff Kirsher * pointer to an element with a specific criteria and NULL if such an element 1050adfc5217SJeff Kirsher * hasn't been found. 1051adfc5217SJeff Kirsher */ 1052adfc5217SJeff Kirsher static struct bnx2x_exeq_elem *bnx2x_exeq_get_mac( 1053adfc5217SJeff Kirsher struct bnx2x_exe_queue_obj *o, 1054adfc5217SJeff Kirsher struct bnx2x_exeq_elem *elem) 1055adfc5217SJeff Kirsher { 1056adfc5217SJeff Kirsher struct bnx2x_exeq_elem *pos; 1057adfc5217SJeff Kirsher struct bnx2x_mac_ramrod_data *data = &elem->cmd_data.vlan_mac.u.mac; 1058adfc5217SJeff Kirsher 1059adfc5217SJeff Kirsher /* Check pending for execution commands */ 1060adfc5217SJeff Kirsher list_for_each_entry(pos, &o->exe_queue, link) 1061adfc5217SJeff Kirsher if (!memcmp(&pos->cmd_data.vlan_mac.u.mac, data, 1062adfc5217SJeff Kirsher sizeof(*data)) && 1063adfc5217SJeff Kirsher (pos->cmd_data.vlan_mac.cmd == elem->cmd_data.vlan_mac.cmd)) 1064adfc5217SJeff Kirsher return pos; 1065adfc5217SJeff Kirsher 1066adfc5217SJeff Kirsher return NULL; 1067adfc5217SJeff Kirsher } 1068adfc5217SJeff Kirsher 1069adfc5217SJeff Kirsher static struct bnx2x_exeq_elem *bnx2x_exeq_get_vlan( 1070adfc5217SJeff Kirsher struct bnx2x_exe_queue_obj *o, 1071adfc5217SJeff Kirsher struct bnx2x_exeq_elem *elem) 1072adfc5217SJeff Kirsher { 1073adfc5217SJeff Kirsher struct bnx2x_exeq_elem *pos; 1074adfc5217SJeff Kirsher struct bnx2x_vlan_ramrod_data *data = &elem->cmd_data.vlan_mac.u.vlan; 1075adfc5217SJeff Kirsher 1076adfc5217SJeff Kirsher /* Check pending for execution commands */ 1077adfc5217SJeff Kirsher list_for_each_entry(pos, &o->exe_queue, link) 1078adfc5217SJeff Kirsher if (!memcmp(&pos->cmd_data.vlan_mac.u.vlan, data, 1079adfc5217SJeff Kirsher sizeof(*data)) && 1080adfc5217SJeff Kirsher (pos->cmd_data.vlan_mac.cmd == elem->cmd_data.vlan_mac.cmd)) 1081adfc5217SJeff Kirsher return pos; 1082adfc5217SJeff Kirsher 1083adfc5217SJeff Kirsher return NULL; 1084adfc5217SJeff Kirsher } 1085adfc5217SJeff Kirsher 1086adfc5217SJeff Kirsher static struct bnx2x_exeq_elem *bnx2x_exeq_get_vlan_mac( 1087adfc5217SJeff Kirsher struct bnx2x_exe_queue_obj *o, 1088adfc5217SJeff Kirsher struct bnx2x_exeq_elem *elem) 1089adfc5217SJeff Kirsher { 1090adfc5217SJeff Kirsher struct bnx2x_exeq_elem *pos; 1091adfc5217SJeff Kirsher struct bnx2x_vlan_mac_ramrod_data *data = 1092adfc5217SJeff Kirsher &elem->cmd_data.vlan_mac.u.vlan_mac; 1093adfc5217SJeff Kirsher 1094adfc5217SJeff Kirsher /* Check pending for execution commands */ 1095adfc5217SJeff Kirsher list_for_each_entry(pos, &o->exe_queue, link) 1096adfc5217SJeff Kirsher if (!memcmp(&pos->cmd_data.vlan_mac.u.vlan_mac, data, 1097adfc5217SJeff Kirsher sizeof(*data)) && 1098adfc5217SJeff Kirsher (pos->cmd_data.vlan_mac.cmd == elem->cmd_data.vlan_mac.cmd)) 1099adfc5217SJeff Kirsher return pos; 1100adfc5217SJeff Kirsher 1101adfc5217SJeff Kirsher return NULL; 1102adfc5217SJeff Kirsher } 1103adfc5217SJeff Kirsher 1104adfc5217SJeff Kirsher /** 1105adfc5217SJeff Kirsher * bnx2x_validate_vlan_mac_add - check if an ADD command can be executed 1106adfc5217SJeff Kirsher * 1107adfc5217SJeff Kirsher * @bp: device handle 1108adfc5217SJeff Kirsher * @qo: bnx2x_qable_obj 1109adfc5217SJeff Kirsher * @elem: bnx2x_exeq_elem 1110adfc5217SJeff Kirsher * 1111adfc5217SJeff Kirsher * Checks that the requested configuration can be added. If yes and if 1112adfc5217SJeff Kirsher * requested, consume CAM credit. 1113adfc5217SJeff Kirsher * 1114adfc5217SJeff Kirsher * The 'validate' is run after the 'optimize'. 1115adfc5217SJeff Kirsher * 1116adfc5217SJeff Kirsher */ 1117adfc5217SJeff Kirsher static inline int bnx2x_validate_vlan_mac_add(struct bnx2x *bp, 1118adfc5217SJeff Kirsher union bnx2x_qable_obj *qo, 1119adfc5217SJeff Kirsher struct bnx2x_exeq_elem *elem) 1120adfc5217SJeff Kirsher { 1121adfc5217SJeff Kirsher struct bnx2x_vlan_mac_obj *o = &qo->vlan_mac; 1122adfc5217SJeff Kirsher struct bnx2x_exe_queue_obj *exeq = &o->exe_queue; 1123adfc5217SJeff Kirsher int rc; 1124adfc5217SJeff Kirsher 1125adfc5217SJeff Kirsher /* Check the registry */ 1126adfc5217SJeff Kirsher rc = o->check_add(o, &elem->cmd_data.vlan_mac.u); 1127adfc5217SJeff Kirsher if (rc) { 1128adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "ADD command is not allowed considering " 1129adfc5217SJeff Kirsher "current registry state\n"); 1130adfc5217SJeff Kirsher return rc; 1131adfc5217SJeff Kirsher } 1132adfc5217SJeff Kirsher 1133adfc5217SJeff Kirsher /* 1134adfc5217SJeff Kirsher * Check if there is a pending ADD command for this 1135adfc5217SJeff Kirsher * MAC/VLAN/VLAN-MAC. Return an error if there is. 1136adfc5217SJeff Kirsher */ 1137adfc5217SJeff Kirsher if (exeq->get(exeq, elem)) { 1138adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "There is a pending ADD command already\n"); 1139adfc5217SJeff Kirsher return -EEXIST; 1140adfc5217SJeff Kirsher } 1141adfc5217SJeff Kirsher 1142adfc5217SJeff Kirsher /* 1143adfc5217SJeff Kirsher * TODO: Check the pending MOVE from other objects where this 1144adfc5217SJeff Kirsher * object is a destination object. 1145adfc5217SJeff Kirsher */ 1146adfc5217SJeff Kirsher 1147adfc5217SJeff Kirsher /* Consume the credit if not requested not to */ 1148adfc5217SJeff Kirsher if (!(test_bit(BNX2X_DONT_CONSUME_CAM_CREDIT, 1149adfc5217SJeff Kirsher &elem->cmd_data.vlan_mac.vlan_mac_flags) || 1150adfc5217SJeff Kirsher o->get_credit(o))) 1151adfc5217SJeff Kirsher return -EINVAL; 1152adfc5217SJeff Kirsher 1153adfc5217SJeff Kirsher return 0; 1154adfc5217SJeff Kirsher } 1155adfc5217SJeff Kirsher 1156adfc5217SJeff Kirsher /** 1157adfc5217SJeff Kirsher * bnx2x_validate_vlan_mac_del - check if the DEL command can be executed 1158adfc5217SJeff Kirsher * 1159adfc5217SJeff Kirsher * @bp: device handle 1160adfc5217SJeff Kirsher * @qo: quable object to check 1161adfc5217SJeff Kirsher * @elem: element that needs to be deleted 1162adfc5217SJeff Kirsher * 1163adfc5217SJeff Kirsher * Checks that the requested configuration can be deleted. If yes and if 1164adfc5217SJeff Kirsher * requested, returns a CAM credit. 1165adfc5217SJeff Kirsher * 1166adfc5217SJeff Kirsher * The 'validate' is run after the 'optimize'. 1167adfc5217SJeff Kirsher */ 1168adfc5217SJeff Kirsher static inline int bnx2x_validate_vlan_mac_del(struct bnx2x *bp, 1169adfc5217SJeff Kirsher union bnx2x_qable_obj *qo, 1170adfc5217SJeff Kirsher struct bnx2x_exeq_elem *elem) 1171adfc5217SJeff Kirsher { 1172adfc5217SJeff Kirsher struct bnx2x_vlan_mac_obj *o = &qo->vlan_mac; 1173adfc5217SJeff Kirsher struct bnx2x_vlan_mac_registry_elem *pos; 1174adfc5217SJeff Kirsher struct bnx2x_exe_queue_obj *exeq = &o->exe_queue; 1175adfc5217SJeff Kirsher struct bnx2x_exeq_elem query_elem; 1176adfc5217SJeff Kirsher 1177adfc5217SJeff Kirsher /* If this classification can not be deleted (doesn't exist) 1178adfc5217SJeff Kirsher * - return a BNX2X_EXIST. 1179adfc5217SJeff Kirsher */ 1180adfc5217SJeff Kirsher pos = o->check_del(o, &elem->cmd_data.vlan_mac.u); 1181adfc5217SJeff Kirsher if (!pos) { 1182adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "DEL command is not allowed considering " 1183adfc5217SJeff Kirsher "current registry state\n"); 1184adfc5217SJeff Kirsher return -EEXIST; 1185adfc5217SJeff Kirsher } 1186adfc5217SJeff Kirsher 1187adfc5217SJeff Kirsher /* 1188adfc5217SJeff Kirsher * Check if there are pending DEL or MOVE commands for this 1189adfc5217SJeff Kirsher * MAC/VLAN/VLAN-MAC. Return an error if so. 1190adfc5217SJeff Kirsher */ 1191adfc5217SJeff Kirsher memcpy(&query_elem, elem, sizeof(query_elem)); 1192adfc5217SJeff Kirsher 1193adfc5217SJeff Kirsher /* Check for MOVE commands */ 1194adfc5217SJeff Kirsher query_elem.cmd_data.vlan_mac.cmd = BNX2X_VLAN_MAC_MOVE; 1195adfc5217SJeff Kirsher if (exeq->get(exeq, &query_elem)) { 1196adfc5217SJeff Kirsher BNX2X_ERR("There is a pending MOVE command already\n"); 1197adfc5217SJeff Kirsher return -EINVAL; 1198adfc5217SJeff Kirsher } 1199adfc5217SJeff Kirsher 1200adfc5217SJeff Kirsher /* Check for DEL commands */ 1201adfc5217SJeff Kirsher if (exeq->get(exeq, elem)) { 1202adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "There is a pending DEL command already\n"); 1203adfc5217SJeff Kirsher return -EEXIST; 1204adfc5217SJeff Kirsher } 1205adfc5217SJeff Kirsher 1206adfc5217SJeff Kirsher /* Return the credit to the credit pool if not requested not to */ 1207adfc5217SJeff Kirsher if (!(test_bit(BNX2X_DONT_CONSUME_CAM_CREDIT, 1208adfc5217SJeff Kirsher &elem->cmd_data.vlan_mac.vlan_mac_flags) || 1209adfc5217SJeff Kirsher o->put_credit(o))) { 1210adfc5217SJeff Kirsher BNX2X_ERR("Failed to return a credit\n"); 1211adfc5217SJeff Kirsher return -EINVAL; 1212adfc5217SJeff Kirsher } 1213adfc5217SJeff Kirsher 1214adfc5217SJeff Kirsher return 0; 1215adfc5217SJeff Kirsher } 1216adfc5217SJeff Kirsher 1217adfc5217SJeff Kirsher /** 1218adfc5217SJeff Kirsher * bnx2x_validate_vlan_mac_move - check if the MOVE command can be executed 1219adfc5217SJeff Kirsher * 1220adfc5217SJeff Kirsher * @bp: device handle 1221adfc5217SJeff Kirsher * @qo: quable object to check (source) 1222adfc5217SJeff Kirsher * @elem: element that needs to be moved 1223adfc5217SJeff Kirsher * 1224adfc5217SJeff Kirsher * Checks that the requested configuration can be moved. If yes and if 1225adfc5217SJeff Kirsher * requested, returns a CAM credit. 1226adfc5217SJeff Kirsher * 1227adfc5217SJeff Kirsher * The 'validate' is run after the 'optimize'. 1228adfc5217SJeff Kirsher */ 1229adfc5217SJeff Kirsher static inline int bnx2x_validate_vlan_mac_move(struct bnx2x *bp, 1230adfc5217SJeff Kirsher union bnx2x_qable_obj *qo, 1231adfc5217SJeff Kirsher struct bnx2x_exeq_elem *elem) 1232adfc5217SJeff Kirsher { 1233adfc5217SJeff Kirsher struct bnx2x_vlan_mac_obj *src_o = &qo->vlan_mac; 1234adfc5217SJeff Kirsher struct bnx2x_vlan_mac_obj *dest_o = elem->cmd_data.vlan_mac.target_obj; 1235adfc5217SJeff Kirsher struct bnx2x_exeq_elem query_elem; 1236adfc5217SJeff Kirsher struct bnx2x_exe_queue_obj *src_exeq = &src_o->exe_queue; 1237adfc5217SJeff Kirsher struct bnx2x_exe_queue_obj *dest_exeq = &dest_o->exe_queue; 1238adfc5217SJeff Kirsher 1239adfc5217SJeff Kirsher /* 1240adfc5217SJeff Kirsher * Check if we can perform this operation based on the current registry 1241adfc5217SJeff Kirsher * state. 1242adfc5217SJeff Kirsher */ 1243adfc5217SJeff Kirsher if (!src_o->check_move(src_o, dest_o, &elem->cmd_data.vlan_mac.u)) { 1244adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "MOVE command is not allowed considering " 1245adfc5217SJeff Kirsher "current registry state\n"); 1246adfc5217SJeff Kirsher return -EINVAL; 1247adfc5217SJeff Kirsher } 1248adfc5217SJeff Kirsher 1249adfc5217SJeff Kirsher /* 1250adfc5217SJeff Kirsher * Check if there is an already pending DEL or MOVE command for the 1251adfc5217SJeff Kirsher * source object or ADD command for a destination object. Return an 1252adfc5217SJeff Kirsher * error if so. 1253adfc5217SJeff Kirsher */ 1254adfc5217SJeff Kirsher memcpy(&query_elem, elem, sizeof(query_elem)); 1255adfc5217SJeff Kirsher 1256adfc5217SJeff Kirsher /* Check DEL on source */ 1257adfc5217SJeff Kirsher query_elem.cmd_data.vlan_mac.cmd = BNX2X_VLAN_MAC_DEL; 1258adfc5217SJeff Kirsher if (src_exeq->get(src_exeq, &query_elem)) { 1259adfc5217SJeff Kirsher BNX2X_ERR("There is a pending DEL command on the source " 1260adfc5217SJeff Kirsher "queue already\n"); 1261adfc5217SJeff Kirsher return -EINVAL; 1262adfc5217SJeff Kirsher } 1263adfc5217SJeff Kirsher 1264adfc5217SJeff Kirsher /* Check MOVE on source */ 1265adfc5217SJeff Kirsher if (src_exeq->get(src_exeq, elem)) { 1266adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "There is a pending MOVE command already\n"); 1267adfc5217SJeff Kirsher return -EEXIST; 1268adfc5217SJeff Kirsher } 1269adfc5217SJeff Kirsher 1270adfc5217SJeff Kirsher /* Check ADD on destination */ 1271adfc5217SJeff Kirsher query_elem.cmd_data.vlan_mac.cmd = BNX2X_VLAN_MAC_ADD; 1272adfc5217SJeff Kirsher if (dest_exeq->get(dest_exeq, &query_elem)) { 1273adfc5217SJeff Kirsher BNX2X_ERR("There is a pending ADD command on the " 1274adfc5217SJeff Kirsher "destination queue already\n"); 1275adfc5217SJeff Kirsher return -EINVAL; 1276adfc5217SJeff Kirsher } 1277adfc5217SJeff Kirsher 1278adfc5217SJeff Kirsher /* Consume the credit if not requested not to */ 1279adfc5217SJeff Kirsher if (!(test_bit(BNX2X_DONT_CONSUME_CAM_CREDIT_DEST, 1280adfc5217SJeff Kirsher &elem->cmd_data.vlan_mac.vlan_mac_flags) || 1281adfc5217SJeff Kirsher dest_o->get_credit(dest_o))) 1282adfc5217SJeff Kirsher return -EINVAL; 1283adfc5217SJeff Kirsher 1284adfc5217SJeff Kirsher if (!(test_bit(BNX2X_DONT_CONSUME_CAM_CREDIT, 1285adfc5217SJeff Kirsher &elem->cmd_data.vlan_mac.vlan_mac_flags) || 1286adfc5217SJeff Kirsher src_o->put_credit(src_o))) { 1287adfc5217SJeff Kirsher /* return the credit taken from dest... */ 1288adfc5217SJeff Kirsher dest_o->put_credit(dest_o); 1289adfc5217SJeff Kirsher return -EINVAL; 1290adfc5217SJeff Kirsher } 1291adfc5217SJeff Kirsher 1292adfc5217SJeff Kirsher return 0; 1293adfc5217SJeff Kirsher } 1294adfc5217SJeff Kirsher 1295adfc5217SJeff Kirsher static int bnx2x_validate_vlan_mac(struct bnx2x *bp, 1296adfc5217SJeff Kirsher union bnx2x_qable_obj *qo, 1297adfc5217SJeff Kirsher struct bnx2x_exeq_elem *elem) 1298adfc5217SJeff Kirsher { 1299adfc5217SJeff Kirsher switch (elem->cmd_data.vlan_mac.cmd) { 1300adfc5217SJeff Kirsher case BNX2X_VLAN_MAC_ADD: 1301adfc5217SJeff Kirsher return bnx2x_validate_vlan_mac_add(bp, qo, elem); 1302adfc5217SJeff Kirsher case BNX2X_VLAN_MAC_DEL: 1303adfc5217SJeff Kirsher return bnx2x_validate_vlan_mac_del(bp, qo, elem); 1304adfc5217SJeff Kirsher case BNX2X_VLAN_MAC_MOVE: 1305adfc5217SJeff Kirsher return bnx2x_validate_vlan_mac_move(bp, qo, elem); 1306adfc5217SJeff Kirsher default: 1307adfc5217SJeff Kirsher return -EINVAL; 1308adfc5217SJeff Kirsher } 1309adfc5217SJeff Kirsher } 1310adfc5217SJeff Kirsher 1311adfc5217SJeff Kirsher /** 1312adfc5217SJeff Kirsher * bnx2x_wait_vlan_mac - passivly wait for 5 seconds until all work completes. 1313adfc5217SJeff Kirsher * 1314adfc5217SJeff Kirsher * @bp: device handle 1315adfc5217SJeff Kirsher * @o: bnx2x_vlan_mac_obj 1316adfc5217SJeff Kirsher * 1317adfc5217SJeff Kirsher */ 1318adfc5217SJeff Kirsher static int bnx2x_wait_vlan_mac(struct bnx2x *bp, 1319adfc5217SJeff Kirsher struct bnx2x_vlan_mac_obj *o) 1320adfc5217SJeff Kirsher { 1321adfc5217SJeff Kirsher int cnt = 5000, rc; 1322adfc5217SJeff Kirsher struct bnx2x_exe_queue_obj *exeq = &o->exe_queue; 1323adfc5217SJeff Kirsher struct bnx2x_raw_obj *raw = &o->raw; 1324adfc5217SJeff Kirsher 1325adfc5217SJeff Kirsher while (cnt--) { 1326adfc5217SJeff Kirsher /* Wait for the current command to complete */ 1327adfc5217SJeff Kirsher rc = raw->wait_comp(bp, raw); 1328adfc5217SJeff Kirsher if (rc) 1329adfc5217SJeff Kirsher return rc; 1330adfc5217SJeff Kirsher 1331adfc5217SJeff Kirsher /* Wait until there are no pending commands */ 1332adfc5217SJeff Kirsher if (!bnx2x_exe_queue_empty(exeq)) 1333adfc5217SJeff Kirsher usleep_range(1000, 1000); 1334adfc5217SJeff Kirsher else 1335adfc5217SJeff Kirsher return 0; 1336adfc5217SJeff Kirsher } 1337adfc5217SJeff Kirsher 1338adfc5217SJeff Kirsher return -EBUSY; 1339adfc5217SJeff Kirsher } 1340adfc5217SJeff Kirsher 1341adfc5217SJeff Kirsher /** 1342adfc5217SJeff Kirsher * bnx2x_complete_vlan_mac - complete one VLAN-MAC ramrod 1343adfc5217SJeff Kirsher * 1344adfc5217SJeff Kirsher * @bp: device handle 1345adfc5217SJeff Kirsher * @o: bnx2x_vlan_mac_obj 1346adfc5217SJeff Kirsher * @cqe: 1347adfc5217SJeff Kirsher * @cont: if true schedule next execution chunk 1348adfc5217SJeff Kirsher * 1349adfc5217SJeff Kirsher */ 1350adfc5217SJeff Kirsher static int bnx2x_complete_vlan_mac(struct bnx2x *bp, 1351adfc5217SJeff Kirsher struct bnx2x_vlan_mac_obj *o, 1352adfc5217SJeff Kirsher union event_ring_elem *cqe, 1353adfc5217SJeff Kirsher unsigned long *ramrod_flags) 1354adfc5217SJeff Kirsher { 1355adfc5217SJeff Kirsher struct bnx2x_raw_obj *r = &o->raw; 1356adfc5217SJeff Kirsher int rc; 1357adfc5217SJeff Kirsher 1358adfc5217SJeff Kirsher /* Reset pending list */ 1359adfc5217SJeff Kirsher bnx2x_exe_queue_reset_pending(bp, &o->exe_queue); 1360adfc5217SJeff Kirsher 1361adfc5217SJeff Kirsher /* Clear pending */ 1362adfc5217SJeff Kirsher r->clear_pending(r); 1363adfc5217SJeff Kirsher 1364adfc5217SJeff Kirsher /* If ramrod failed this is most likely a SW bug */ 1365adfc5217SJeff Kirsher if (cqe->message.error) 1366adfc5217SJeff Kirsher return -EINVAL; 1367adfc5217SJeff Kirsher 1368adfc5217SJeff Kirsher /* Run the next bulk of pending commands if requeted */ 1369adfc5217SJeff Kirsher if (test_bit(RAMROD_CONT, ramrod_flags)) { 1370adfc5217SJeff Kirsher rc = bnx2x_exe_queue_step(bp, &o->exe_queue, ramrod_flags); 1371adfc5217SJeff Kirsher if (rc < 0) 1372adfc5217SJeff Kirsher return rc; 1373adfc5217SJeff Kirsher } 1374adfc5217SJeff Kirsher 1375adfc5217SJeff Kirsher /* If there is more work to do return PENDING */ 1376adfc5217SJeff Kirsher if (!bnx2x_exe_queue_empty(&o->exe_queue)) 1377adfc5217SJeff Kirsher return 1; 1378adfc5217SJeff Kirsher 1379adfc5217SJeff Kirsher return 0; 1380adfc5217SJeff Kirsher } 1381adfc5217SJeff Kirsher 1382adfc5217SJeff Kirsher /** 1383adfc5217SJeff Kirsher * bnx2x_optimize_vlan_mac - optimize ADD and DEL commands. 1384adfc5217SJeff Kirsher * 1385adfc5217SJeff Kirsher * @bp: device handle 1386adfc5217SJeff Kirsher * @o: bnx2x_qable_obj 1387adfc5217SJeff Kirsher * @elem: bnx2x_exeq_elem 1388adfc5217SJeff Kirsher */ 1389adfc5217SJeff Kirsher static int bnx2x_optimize_vlan_mac(struct bnx2x *bp, 1390adfc5217SJeff Kirsher union bnx2x_qable_obj *qo, 1391adfc5217SJeff Kirsher struct bnx2x_exeq_elem *elem) 1392adfc5217SJeff Kirsher { 1393adfc5217SJeff Kirsher struct bnx2x_exeq_elem query, *pos; 1394adfc5217SJeff Kirsher struct bnx2x_vlan_mac_obj *o = &qo->vlan_mac; 1395adfc5217SJeff Kirsher struct bnx2x_exe_queue_obj *exeq = &o->exe_queue; 1396adfc5217SJeff Kirsher 1397adfc5217SJeff Kirsher memcpy(&query, elem, sizeof(query)); 1398adfc5217SJeff Kirsher 1399adfc5217SJeff Kirsher switch (elem->cmd_data.vlan_mac.cmd) { 1400adfc5217SJeff Kirsher case BNX2X_VLAN_MAC_ADD: 1401adfc5217SJeff Kirsher query.cmd_data.vlan_mac.cmd = BNX2X_VLAN_MAC_DEL; 1402adfc5217SJeff Kirsher break; 1403adfc5217SJeff Kirsher case BNX2X_VLAN_MAC_DEL: 1404adfc5217SJeff Kirsher query.cmd_data.vlan_mac.cmd = BNX2X_VLAN_MAC_ADD; 1405adfc5217SJeff Kirsher break; 1406adfc5217SJeff Kirsher default: 1407adfc5217SJeff Kirsher /* Don't handle anything other than ADD or DEL */ 1408adfc5217SJeff Kirsher return 0; 1409adfc5217SJeff Kirsher } 1410adfc5217SJeff Kirsher 1411adfc5217SJeff Kirsher /* If we found the appropriate element - delete it */ 1412adfc5217SJeff Kirsher pos = exeq->get(exeq, &query); 1413adfc5217SJeff Kirsher if (pos) { 1414adfc5217SJeff Kirsher 1415adfc5217SJeff Kirsher /* Return the credit of the optimized command */ 1416adfc5217SJeff Kirsher if (!test_bit(BNX2X_DONT_CONSUME_CAM_CREDIT, 1417adfc5217SJeff Kirsher &pos->cmd_data.vlan_mac.vlan_mac_flags)) { 1418adfc5217SJeff Kirsher if ((query.cmd_data.vlan_mac.cmd == 1419adfc5217SJeff Kirsher BNX2X_VLAN_MAC_ADD) && !o->put_credit(o)) { 1420adfc5217SJeff Kirsher BNX2X_ERR("Failed to return the credit for the " 1421adfc5217SJeff Kirsher "optimized ADD command\n"); 1422adfc5217SJeff Kirsher return -EINVAL; 1423adfc5217SJeff Kirsher } else if (!o->get_credit(o)) { /* VLAN_MAC_DEL */ 1424adfc5217SJeff Kirsher BNX2X_ERR("Failed to recover the credit from " 1425adfc5217SJeff Kirsher "the optimized DEL command\n"); 1426adfc5217SJeff Kirsher return -EINVAL; 1427adfc5217SJeff Kirsher } 1428adfc5217SJeff Kirsher } 1429adfc5217SJeff Kirsher 1430adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "Optimizing %s command\n", 1431adfc5217SJeff Kirsher (elem->cmd_data.vlan_mac.cmd == BNX2X_VLAN_MAC_ADD) ? 1432adfc5217SJeff Kirsher "ADD" : "DEL"); 1433adfc5217SJeff Kirsher 1434adfc5217SJeff Kirsher list_del(&pos->link); 1435adfc5217SJeff Kirsher bnx2x_exe_queue_free_elem(bp, pos); 1436adfc5217SJeff Kirsher return 1; 1437adfc5217SJeff Kirsher } 1438adfc5217SJeff Kirsher 1439adfc5217SJeff Kirsher return 0; 1440adfc5217SJeff Kirsher } 1441adfc5217SJeff Kirsher 1442adfc5217SJeff Kirsher /** 1443adfc5217SJeff Kirsher * bnx2x_vlan_mac_get_registry_elem - prepare a registry element 1444adfc5217SJeff Kirsher * 1445adfc5217SJeff Kirsher * @bp: device handle 1446adfc5217SJeff Kirsher * @o: 1447adfc5217SJeff Kirsher * @elem: 1448adfc5217SJeff Kirsher * @restore: 1449adfc5217SJeff Kirsher * @re: 1450adfc5217SJeff Kirsher * 1451adfc5217SJeff Kirsher * prepare a registry element according to the current command request. 1452adfc5217SJeff Kirsher */ 1453adfc5217SJeff Kirsher static inline int bnx2x_vlan_mac_get_registry_elem( 1454adfc5217SJeff Kirsher struct bnx2x *bp, 1455adfc5217SJeff Kirsher struct bnx2x_vlan_mac_obj *o, 1456adfc5217SJeff Kirsher struct bnx2x_exeq_elem *elem, 1457adfc5217SJeff Kirsher bool restore, 1458adfc5217SJeff Kirsher struct bnx2x_vlan_mac_registry_elem **re) 1459adfc5217SJeff Kirsher { 1460adfc5217SJeff Kirsher int cmd = elem->cmd_data.vlan_mac.cmd; 1461adfc5217SJeff Kirsher struct bnx2x_vlan_mac_registry_elem *reg_elem; 1462adfc5217SJeff Kirsher 1463adfc5217SJeff Kirsher /* Allocate a new registry element if needed. */ 1464adfc5217SJeff Kirsher if (!restore && 1465adfc5217SJeff Kirsher ((cmd == BNX2X_VLAN_MAC_ADD) || (cmd == BNX2X_VLAN_MAC_MOVE))) { 1466adfc5217SJeff Kirsher reg_elem = kzalloc(sizeof(*reg_elem), GFP_ATOMIC); 1467adfc5217SJeff Kirsher if (!reg_elem) 1468adfc5217SJeff Kirsher return -ENOMEM; 1469adfc5217SJeff Kirsher 1470adfc5217SJeff Kirsher /* Get a new CAM offset */ 1471adfc5217SJeff Kirsher if (!o->get_cam_offset(o, ®_elem->cam_offset)) { 1472adfc5217SJeff Kirsher /* 1473adfc5217SJeff Kirsher * This shell never happen, because we have checked the 1474adfc5217SJeff Kirsher * CAM availiability in the 'validate'. 1475adfc5217SJeff Kirsher */ 1476adfc5217SJeff Kirsher WARN_ON(1); 1477adfc5217SJeff Kirsher kfree(reg_elem); 1478adfc5217SJeff Kirsher return -EINVAL; 1479adfc5217SJeff Kirsher } 1480adfc5217SJeff Kirsher 1481adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "Got cam offset %d\n", reg_elem->cam_offset); 1482adfc5217SJeff Kirsher 1483adfc5217SJeff Kirsher /* Set a VLAN-MAC data */ 1484adfc5217SJeff Kirsher memcpy(®_elem->u, &elem->cmd_data.vlan_mac.u, 1485adfc5217SJeff Kirsher sizeof(reg_elem->u)); 1486adfc5217SJeff Kirsher 1487adfc5217SJeff Kirsher /* Copy the flags (needed for DEL and RESTORE flows) */ 1488adfc5217SJeff Kirsher reg_elem->vlan_mac_flags = 1489adfc5217SJeff Kirsher elem->cmd_data.vlan_mac.vlan_mac_flags; 1490adfc5217SJeff Kirsher } else /* DEL, RESTORE */ 1491adfc5217SJeff Kirsher reg_elem = o->check_del(o, &elem->cmd_data.vlan_mac.u); 1492adfc5217SJeff Kirsher 1493adfc5217SJeff Kirsher *re = reg_elem; 1494adfc5217SJeff Kirsher return 0; 1495adfc5217SJeff Kirsher } 1496adfc5217SJeff Kirsher 1497adfc5217SJeff Kirsher /** 1498adfc5217SJeff Kirsher * bnx2x_execute_vlan_mac - execute vlan mac command 1499adfc5217SJeff Kirsher * 1500adfc5217SJeff Kirsher * @bp: device handle 1501adfc5217SJeff Kirsher * @qo: 1502adfc5217SJeff Kirsher * @exe_chunk: 1503adfc5217SJeff Kirsher * @ramrod_flags: 1504adfc5217SJeff Kirsher * 1505adfc5217SJeff Kirsher * go and send a ramrod! 1506adfc5217SJeff Kirsher */ 1507adfc5217SJeff Kirsher static int bnx2x_execute_vlan_mac(struct bnx2x *bp, 1508adfc5217SJeff Kirsher union bnx2x_qable_obj *qo, 1509adfc5217SJeff Kirsher struct list_head *exe_chunk, 1510adfc5217SJeff Kirsher unsigned long *ramrod_flags) 1511adfc5217SJeff Kirsher { 1512adfc5217SJeff Kirsher struct bnx2x_exeq_elem *elem; 1513adfc5217SJeff Kirsher struct bnx2x_vlan_mac_obj *o = &qo->vlan_mac, *cam_obj; 1514adfc5217SJeff Kirsher struct bnx2x_raw_obj *r = &o->raw; 1515adfc5217SJeff Kirsher int rc, idx = 0; 1516adfc5217SJeff Kirsher bool restore = test_bit(RAMROD_RESTORE, ramrod_flags); 1517adfc5217SJeff Kirsher bool drv_only = test_bit(RAMROD_DRV_CLR_ONLY, ramrod_flags); 1518adfc5217SJeff Kirsher struct bnx2x_vlan_mac_registry_elem *reg_elem; 1519adfc5217SJeff Kirsher int cmd; 1520adfc5217SJeff Kirsher 1521adfc5217SJeff Kirsher /* 1522adfc5217SJeff Kirsher * If DRIVER_ONLY execution is requested, cleanup a registry 1523adfc5217SJeff Kirsher * and exit. Otherwise send a ramrod to FW. 1524adfc5217SJeff Kirsher */ 1525adfc5217SJeff Kirsher if (!drv_only) { 1526adfc5217SJeff Kirsher WARN_ON(r->check_pending(r)); 1527adfc5217SJeff Kirsher 1528adfc5217SJeff Kirsher /* Set pending */ 1529adfc5217SJeff Kirsher r->set_pending(r); 1530adfc5217SJeff Kirsher 1531adfc5217SJeff Kirsher /* Fill tha ramrod data */ 1532adfc5217SJeff Kirsher list_for_each_entry(elem, exe_chunk, link) { 1533adfc5217SJeff Kirsher cmd = elem->cmd_data.vlan_mac.cmd; 1534adfc5217SJeff Kirsher /* 1535adfc5217SJeff Kirsher * We will add to the target object in MOVE command, so 1536adfc5217SJeff Kirsher * change the object for a CAM search. 1537adfc5217SJeff Kirsher */ 1538adfc5217SJeff Kirsher if (cmd == BNX2X_VLAN_MAC_MOVE) 1539adfc5217SJeff Kirsher cam_obj = elem->cmd_data.vlan_mac.target_obj; 1540adfc5217SJeff Kirsher else 1541adfc5217SJeff Kirsher cam_obj = o; 1542adfc5217SJeff Kirsher 1543adfc5217SJeff Kirsher rc = bnx2x_vlan_mac_get_registry_elem(bp, cam_obj, 1544adfc5217SJeff Kirsher elem, restore, 1545adfc5217SJeff Kirsher ®_elem); 1546adfc5217SJeff Kirsher if (rc) 1547adfc5217SJeff Kirsher goto error_exit; 1548adfc5217SJeff Kirsher 1549adfc5217SJeff Kirsher WARN_ON(!reg_elem); 1550adfc5217SJeff Kirsher 1551adfc5217SJeff Kirsher /* Push a new entry into the registry */ 1552adfc5217SJeff Kirsher if (!restore && 1553adfc5217SJeff Kirsher ((cmd == BNX2X_VLAN_MAC_ADD) || 1554adfc5217SJeff Kirsher (cmd == BNX2X_VLAN_MAC_MOVE))) 1555adfc5217SJeff Kirsher list_add(®_elem->link, &cam_obj->head); 1556adfc5217SJeff Kirsher 1557adfc5217SJeff Kirsher /* Configure a single command in a ramrod data buffer */ 1558adfc5217SJeff Kirsher o->set_one_rule(bp, o, elem, idx, 1559adfc5217SJeff Kirsher reg_elem->cam_offset); 1560adfc5217SJeff Kirsher 1561adfc5217SJeff Kirsher /* MOVE command consumes 2 entries in the ramrod data */ 1562adfc5217SJeff Kirsher if (cmd == BNX2X_VLAN_MAC_MOVE) 1563adfc5217SJeff Kirsher idx += 2; 1564adfc5217SJeff Kirsher else 1565adfc5217SJeff Kirsher idx++; 1566adfc5217SJeff Kirsher } 1567adfc5217SJeff Kirsher 1568adfc5217SJeff Kirsher /* 1569adfc5217SJeff Kirsher * No need for an explicit memory barrier here as long we would 1570adfc5217SJeff Kirsher * need to ensure the ordering of writing to the SPQ element 1571adfc5217SJeff Kirsher * and updating of the SPQ producer which involves a memory 1572adfc5217SJeff Kirsher * read and we will have to put a full memory barrier there 1573adfc5217SJeff Kirsher * (inside bnx2x_sp_post()). 1574adfc5217SJeff Kirsher */ 1575adfc5217SJeff Kirsher 1576adfc5217SJeff Kirsher rc = bnx2x_sp_post(bp, o->ramrod_cmd, r->cid, 1577adfc5217SJeff Kirsher U64_HI(r->rdata_mapping), 1578adfc5217SJeff Kirsher U64_LO(r->rdata_mapping), 1579adfc5217SJeff Kirsher ETH_CONNECTION_TYPE); 1580adfc5217SJeff Kirsher if (rc) 1581adfc5217SJeff Kirsher goto error_exit; 1582adfc5217SJeff Kirsher } 1583adfc5217SJeff Kirsher 1584adfc5217SJeff Kirsher /* Now, when we are done with the ramrod - clean up the registry */ 1585adfc5217SJeff Kirsher list_for_each_entry(elem, exe_chunk, link) { 1586adfc5217SJeff Kirsher cmd = elem->cmd_data.vlan_mac.cmd; 1587adfc5217SJeff Kirsher if ((cmd == BNX2X_VLAN_MAC_DEL) || 1588adfc5217SJeff Kirsher (cmd == BNX2X_VLAN_MAC_MOVE)) { 1589adfc5217SJeff Kirsher reg_elem = o->check_del(o, &elem->cmd_data.vlan_mac.u); 1590adfc5217SJeff Kirsher 1591adfc5217SJeff Kirsher WARN_ON(!reg_elem); 1592adfc5217SJeff Kirsher 1593adfc5217SJeff Kirsher o->put_cam_offset(o, reg_elem->cam_offset); 1594adfc5217SJeff Kirsher list_del(®_elem->link); 1595adfc5217SJeff Kirsher kfree(reg_elem); 1596adfc5217SJeff Kirsher } 1597adfc5217SJeff Kirsher } 1598adfc5217SJeff Kirsher 1599adfc5217SJeff Kirsher if (!drv_only) 1600adfc5217SJeff Kirsher return 1; 1601adfc5217SJeff Kirsher else 1602adfc5217SJeff Kirsher return 0; 1603adfc5217SJeff Kirsher 1604adfc5217SJeff Kirsher error_exit: 1605adfc5217SJeff Kirsher r->clear_pending(r); 1606adfc5217SJeff Kirsher 1607adfc5217SJeff Kirsher /* Cleanup a registry in case of a failure */ 1608adfc5217SJeff Kirsher list_for_each_entry(elem, exe_chunk, link) { 1609adfc5217SJeff Kirsher cmd = elem->cmd_data.vlan_mac.cmd; 1610adfc5217SJeff Kirsher 1611adfc5217SJeff Kirsher if (cmd == BNX2X_VLAN_MAC_MOVE) 1612adfc5217SJeff Kirsher cam_obj = elem->cmd_data.vlan_mac.target_obj; 1613adfc5217SJeff Kirsher else 1614adfc5217SJeff Kirsher cam_obj = o; 1615adfc5217SJeff Kirsher 1616adfc5217SJeff Kirsher /* Delete all newly added above entries */ 1617adfc5217SJeff Kirsher if (!restore && 1618adfc5217SJeff Kirsher ((cmd == BNX2X_VLAN_MAC_ADD) || 1619adfc5217SJeff Kirsher (cmd == BNX2X_VLAN_MAC_MOVE))) { 1620adfc5217SJeff Kirsher reg_elem = o->check_del(cam_obj, 1621adfc5217SJeff Kirsher &elem->cmd_data.vlan_mac.u); 1622adfc5217SJeff Kirsher if (reg_elem) { 1623adfc5217SJeff Kirsher list_del(®_elem->link); 1624adfc5217SJeff Kirsher kfree(reg_elem); 1625adfc5217SJeff Kirsher } 1626adfc5217SJeff Kirsher } 1627adfc5217SJeff Kirsher } 1628adfc5217SJeff Kirsher 1629adfc5217SJeff Kirsher return rc; 1630adfc5217SJeff Kirsher } 1631adfc5217SJeff Kirsher 1632adfc5217SJeff Kirsher static inline int bnx2x_vlan_mac_push_new_cmd( 1633adfc5217SJeff Kirsher struct bnx2x *bp, 1634adfc5217SJeff Kirsher struct bnx2x_vlan_mac_ramrod_params *p) 1635adfc5217SJeff Kirsher { 1636adfc5217SJeff Kirsher struct bnx2x_exeq_elem *elem; 1637adfc5217SJeff Kirsher struct bnx2x_vlan_mac_obj *o = p->vlan_mac_obj; 1638adfc5217SJeff Kirsher bool restore = test_bit(RAMROD_RESTORE, &p->ramrod_flags); 1639adfc5217SJeff Kirsher 1640adfc5217SJeff Kirsher /* Allocate the execution queue element */ 1641adfc5217SJeff Kirsher elem = bnx2x_exe_queue_alloc_elem(bp); 1642adfc5217SJeff Kirsher if (!elem) 1643adfc5217SJeff Kirsher return -ENOMEM; 1644adfc5217SJeff Kirsher 1645adfc5217SJeff Kirsher /* Set the command 'length' */ 1646adfc5217SJeff Kirsher switch (p->user_req.cmd) { 1647adfc5217SJeff Kirsher case BNX2X_VLAN_MAC_MOVE: 1648adfc5217SJeff Kirsher elem->cmd_len = 2; 1649adfc5217SJeff Kirsher break; 1650adfc5217SJeff Kirsher default: 1651adfc5217SJeff Kirsher elem->cmd_len = 1; 1652adfc5217SJeff Kirsher } 1653adfc5217SJeff Kirsher 1654adfc5217SJeff Kirsher /* Fill the object specific info */ 1655adfc5217SJeff Kirsher memcpy(&elem->cmd_data.vlan_mac, &p->user_req, sizeof(p->user_req)); 1656adfc5217SJeff Kirsher 1657adfc5217SJeff Kirsher /* Try to add a new command to the pending list */ 1658adfc5217SJeff Kirsher return bnx2x_exe_queue_add(bp, &o->exe_queue, elem, restore); 1659adfc5217SJeff Kirsher } 1660adfc5217SJeff Kirsher 1661adfc5217SJeff Kirsher /** 1662adfc5217SJeff Kirsher * bnx2x_config_vlan_mac - configure VLAN/MAC/VLAN_MAC filtering rules. 1663adfc5217SJeff Kirsher * 1664adfc5217SJeff Kirsher * @bp: device handle 1665adfc5217SJeff Kirsher * @p: 1666adfc5217SJeff Kirsher * 1667adfc5217SJeff Kirsher */ 1668adfc5217SJeff Kirsher int bnx2x_config_vlan_mac( 1669adfc5217SJeff Kirsher struct bnx2x *bp, 1670adfc5217SJeff Kirsher struct bnx2x_vlan_mac_ramrod_params *p) 1671adfc5217SJeff Kirsher { 1672adfc5217SJeff Kirsher int rc = 0; 1673adfc5217SJeff Kirsher struct bnx2x_vlan_mac_obj *o = p->vlan_mac_obj; 1674adfc5217SJeff Kirsher unsigned long *ramrod_flags = &p->ramrod_flags; 1675adfc5217SJeff Kirsher bool cont = test_bit(RAMROD_CONT, ramrod_flags); 1676adfc5217SJeff Kirsher struct bnx2x_raw_obj *raw = &o->raw; 1677adfc5217SJeff Kirsher 1678adfc5217SJeff Kirsher /* 1679adfc5217SJeff Kirsher * Add new elements to the execution list for commands that require it. 1680adfc5217SJeff Kirsher */ 1681adfc5217SJeff Kirsher if (!cont) { 1682adfc5217SJeff Kirsher rc = bnx2x_vlan_mac_push_new_cmd(bp, p); 1683adfc5217SJeff Kirsher if (rc) 1684adfc5217SJeff Kirsher return rc; 1685adfc5217SJeff Kirsher } 1686adfc5217SJeff Kirsher 1687adfc5217SJeff Kirsher /* 1688adfc5217SJeff Kirsher * If nothing will be executed further in this iteration we want to 1689adfc5217SJeff Kirsher * return PENDING if there are pending commands 1690adfc5217SJeff Kirsher */ 1691adfc5217SJeff Kirsher if (!bnx2x_exe_queue_empty(&o->exe_queue)) 1692adfc5217SJeff Kirsher rc = 1; 1693adfc5217SJeff Kirsher 1694adfc5217SJeff Kirsher if (test_bit(RAMROD_DRV_CLR_ONLY, ramrod_flags)) { 1695adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "RAMROD_DRV_CLR_ONLY requested: " 1696adfc5217SJeff Kirsher "clearing a pending bit.\n"); 1697adfc5217SJeff Kirsher raw->clear_pending(raw); 1698adfc5217SJeff Kirsher } 1699adfc5217SJeff Kirsher 1700adfc5217SJeff Kirsher /* Execute commands if required */ 1701adfc5217SJeff Kirsher if (cont || test_bit(RAMROD_EXEC, ramrod_flags) || 1702adfc5217SJeff Kirsher test_bit(RAMROD_COMP_WAIT, ramrod_flags)) { 1703adfc5217SJeff Kirsher rc = bnx2x_exe_queue_step(bp, &o->exe_queue, ramrod_flags); 1704adfc5217SJeff Kirsher if (rc < 0) 1705adfc5217SJeff Kirsher return rc; 1706adfc5217SJeff Kirsher } 1707adfc5217SJeff Kirsher 1708adfc5217SJeff Kirsher /* 1709adfc5217SJeff Kirsher * RAMROD_COMP_WAIT is a superset of RAMROD_EXEC. If it was set 1710adfc5217SJeff Kirsher * then user want to wait until the last command is done. 1711adfc5217SJeff Kirsher */ 1712adfc5217SJeff Kirsher if (test_bit(RAMROD_COMP_WAIT, &p->ramrod_flags)) { 1713adfc5217SJeff Kirsher /* 1714adfc5217SJeff Kirsher * Wait maximum for the current exe_queue length iterations plus 1715adfc5217SJeff Kirsher * one (for the current pending command). 1716adfc5217SJeff Kirsher */ 1717adfc5217SJeff Kirsher int max_iterations = bnx2x_exe_queue_length(&o->exe_queue) + 1; 1718adfc5217SJeff Kirsher 1719adfc5217SJeff Kirsher while (!bnx2x_exe_queue_empty(&o->exe_queue) && 1720adfc5217SJeff Kirsher max_iterations--) { 1721adfc5217SJeff Kirsher 1722adfc5217SJeff Kirsher /* Wait for the current command to complete */ 1723adfc5217SJeff Kirsher rc = raw->wait_comp(bp, raw); 1724adfc5217SJeff Kirsher if (rc) 1725adfc5217SJeff Kirsher return rc; 1726adfc5217SJeff Kirsher 1727adfc5217SJeff Kirsher /* Make a next step */ 1728adfc5217SJeff Kirsher rc = bnx2x_exe_queue_step(bp, &o->exe_queue, 1729adfc5217SJeff Kirsher ramrod_flags); 1730adfc5217SJeff Kirsher if (rc < 0) 1731adfc5217SJeff Kirsher return rc; 1732adfc5217SJeff Kirsher } 1733adfc5217SJeff Kirsher 1734adfc5217SJeff Kirsher return 0; 1735adfc5217SJeff Kirsher } 1736adfc5217SJeff Kirsher 1737adfc5217SJeff Kirsher return rc; 1738adfc5217SJeff Kirsher } 1739adfc5217SJeff Kirsher 1740adfc5217SJeff Kirsher 1741adfc5217SJeff Kirsher 1742adfc5217SJeff Kirsher /** 1743adfc5217SJeff Kirsher * bnx2x_vlan_mac_del_all - delete elements with given vlan_mac_flags spec 1744adfc5217SJeff Kirsher * 1745adfc5217SJeff Kirsher * @bp: device handle 1746adfc5217SJeff Kirsher * @o: 1747adfc5217SJeff Kirsher * @vlan_mac_flags: 1748adfc5217SJeff Kirsher * @ramrod_flags: execution flags to be used for this deletion 1749adfc5217SJeff Kirsher * 1750adfc5217SJeff Kirsher * if the last operation has completed successfully and there are no 1751adfc5217SJeff Kirsher * moreelements left, positive value if the last operation has completed 1752adfc5217SJeff Kirsher * successfully and there are more previously configured elements, negative 1753adfc5217SJeff Kirsher * value is current operation has failed. 1754adfc5217SJeff Kirsher */ 1755adfc5217SJeff Kirsher static int bnx2x_vlan_mac_del_all(struct bnx2x *bp, 1756adfc5217SJeff Kirsher struct bnx2x_vlan_mac_obj *o, 1757adfc5217SJeff Kirsher unsigned long *vlan_mac_flags, 1758adfc5217SJeff Kirsher unsigned long *ramrod_flags) 1759adfc5217SJeff Kirsher { 1760adfc5217SJeff Kirsher struct bnx2x_vlan_mac_registry_elem *pos = NULL; 1761adfc5217SJeff Kirsher int rc = 0; 1762adfc5217SJeff Kirsher struct bnx2x_vlan_mac_ramrod_params p; 1763adfc5217SJeff Kirsher struct bnx2x_exe_queue_obj *exeq = &o->exe_queue; 1764adfc5217SJeff Kirsher struct bnx2x_exeq_elem *exeq_pos, *exeq_pos_n; 1765adfc5217SJeff Kirsher 1766adfc5217SJeff Kirsher /* Clear pending commands first */ 1767adfc5217SJeff Kirsher 1768adfc5217SJeff Kirsher spin_lock_bh(&exeq->lock); 1769adfc5217SJeff Kirsher 1770adfc5217SJeff Kirsher list_for_each_entry_safe(exeq_pos, exeq_pos_n, &exeq->exe_queue, link) { 1771adfc5217SJeff Kirsher if (exeq_pos->cmd_data.vlan_mac.vlan_mac_flags == 1772adfc5217SJeff Kirsher *vlan_mac_flags) 1773adfc5217SJeff Kirsher list_del(&exeq_pos->link); 1774adfc5217SJeff Kirsher } 1775adfc5217SJeff Kirsher 1776adfc5217SJeff Kirsher spin_unlock_bh(&exeq->lock); 1777adfc5217SJeff Kirsher 1778adfc5217SJeff Kirsher /* Prepare a command request */ 1779adfc5217SJeff Kirsher memset(&p, 0, sizeof(p)); 1780adfc5217SJeff Kirsher p.vlan_mac_obj = o; 1781adfc5217SJeff Kirsher p.ramrod_flags = *ramrod_flags; 1782adfc5217SJeff Kirsher p.user_req.cmd = BNX2X_VLAN_MAC_DEL; 1783adfc5217SJeff Kirsher 1784adfc5217SJeff Kirsher /* 1785adfc5217SJeff Kirsher * Add all but the last VLAN-MAC to the execution queue without actually 1786adfc5217SJeff Kirsher * execution anything. 1787adfc5217SJeff Kirsher */ 1788adfc5217SJeff Kirsher __clear_bit(RAMROD_COMP_WAIT, &p.ramrod_flags); 1789adfc5217SJeff Kirsher __clear_bit(RAMROD_EXEC, &p.ramrod_flags); 1790adfc5217SJeff Kirsher __clear_bit(RAMROD_CONT, &p.ramrod_flags); 1791adfc5217SJeff Kirsher 1792adfc5217SJeff Kirsher list_for_each_entry(pos, &o->head, link) { 1793adfc5217SJeff Kirsher if (pos->vlan_mac_flags == *vlan_mac_flags) { 1794adfc5217SJeff Kirsher p.user_req.vlan_mac_flags = pos->vlan_mac_flags; 1795adfc5217SJeff Kirsher memcpy(&p.user_req.u, &pos->u, sizeof(pos->u)); 1796adfc5217SJeff Kirsher rc = bnx2x_config_vlan_mac(bp, &p); 1797adfc5217SJeff Kirsher if (rc < 0) { 1798adfc5217SJeff Kirsher BNX2X_ERR("Failed to add a new DEL command\n"); 1799adfc5217SJeff Kirsher return rc; 1800adfc5217SJeff Kirsher } 1801adfc5217SJeff Kirsher } 1802adfc5217SJeff Kirsher } 1803adfc5217SJeff Kirsher 1804adfc5217SJeff Kirsher p.ramrod_flags = *ramrod_flags; 1805adfc5217SJeff Kirsher __set_bit(RAMROD_CONT, &p.ramrod_flags); 1806adfc5217SJeff Kirsher 1807adfc5217SJeff Kirsher return bnx2x_config_vlan_mac(bp, &p); 1808adfc5217SJeff Kirsher } 1809adfc5217SJeff Kirsher 1810adfc5217SJeff Kirsher static inline void bnx2x_init_raw_obj(struct bnx2x_raw_obj *raw, u8 cl_id, 1811adfc5217SJeff Kirsher u32 cid, u8 func_id, void *rdata, dma_addr_t rdata_mapping, int state, 1812adfc5217SJeff Kirsher unsigned long *pstate, bnx2x_obj_type type) 1813adfc5217SJeff Kirsher { 1814adfc5217SJeff Kirsher raw->func_id = func_id; 1815adfc5217SJeff Kirsher raw->cid = cid; 1816adfc5217SJeff Kirsher raw->cl_id = cl_id; 1817adfc5217SJeff Kirsher raw->rdata = rdata; 1818adfc5217SJeff Kirsher raw->rdata_mapping = rdata_mapping; 1819adfc5217SJeff Kirsher raw->state = state; 1820adfc5217SJeff Kirsher raw->pstate = pstate; 1821adfc5217SJeff Kirsher raw->obj_type = type; 1822adfc5217SJeff Kirsher raw->check_pending = bnx2x_raw_check_pending; 1823adfc5217SJeff Kirsher raw->clear_pending = bnx2x_raw_clear_pending; 1824adfc5217SJeff Kirsher raw->set_pending = bnx2x_raw_set_pending; 1825adfc5217SJeff Kirsher raw->wait_comp = bnx2x_raw_wait; 1826adfc5217SJeff Kirsher } 1827adfc5217SJeff Kirsher 1828adfc5217SJeff Kirsher static inline void bnx2x_init_vlan_mac_common(struct bnx2x_vlan_mac_obj *o, 1829adfc5217SJeff Kirsher u8 cl_id, u32 cid, u8 func_id, void *rdata, dma_addr_t rdata_mapping, 1830adfc5217SJeff Kirsher int state, unsigned long *pstate, bnx2x_obj_type type, 1831adfc5217SJeff Kirsher struct bnx2x_credit_pool_obj *macs_pool, 1832adfc5217SJeff Kirsher struct bnx2x_credit_pool_obj *vlans_pool) 1833adfc5217SJeff Kirsher { 1834adfc5217SJeff Kirsher INIT_LIST_HEAD(&o->head); 1835adfc5217SJeff Kirsher 1836adfc5217SJeff Kirsher o->macs_pool = macs_pool; 1837adfc5217SJeff Kirsher o->vlans_pool = vlans_pool; 1838adfc5217SJeff Kirsher 1839adfc5217SJeff Kirsher o->delete_all = bnx2x_vlan_mac_del_all; 1840adfc5217SJeff Kirsher o->restore = bnx2x_vlan_mac_restore; 1841adfc5217SJeff Kirsher o->complete = bnx2x_complete_vlan_mac; 1842adfc5217SJeff Kirsher o->wait = bnx2x_wait_vlan_mac; 1843adfc5217SJeff Kirsher 1844adfc5217SJeff Kirsher bnx2x_init_raw_obj(&o->raw, cl_id, cid, func_id, rdata, rdata_mapping, 1845adfc5217SJeff Kirsher state, pstate, type); 1846adfc5217SJeff Kirsher } 1847adfc5217SJeff Kirsher 1848adfc5217SJeff Kirsher 1849adfc5217SJeff Kirsher void bnx2x_init_mac_obj(struct bnx2x *bp, 1850adfc5217SJeff Kirsher struct bnx2x_vlan_mac_obj *mac_obj, 1851adfc5217SJeff Kirsher u8 cl_id, u32 cid, u8 func_id, void *rdata, 1852adfc5217SJeff Kirsher dma_addr_t rdata_mapping, int state, 1853adfc5217SJeff Kirsher unsigned long *pstate, bnx2x_obj_type type, 1854adfc5217SJeff Kirsher struct bnx2x_credit_pool_obj *macs_pool) 1855adfc5217SJeff Kirsher { 1856adfc5217SJeff Kirsher union bnx2x_qable_obj *qable_obj = (union bnx2x_qable_obj *)mac_obj; 1857adfc5217SJeff Kirsher 1858adfc5217SJeff Kirsher bnx2x_init_vlan_mac_common(mac_obj, cl_id, cid, func_id, rdata, 1859adfc5217SJeff Kirsher rdata_mapping, state, pstate, type, 1860adfc5217SJeff Kirsher macs_pool, NULL); 1861adfc5217SJeff Kirsher 1862adfc5217SJeff Kirsher /* CAM credit pool handling */ 1863adfc5217SJeff Kirsher mac_obj->get_credit = bnx2x_get_credit_mac; 1864adfc5217SJeff Kirsher mac_obj->put_credit = bnx2x_put_credit_mac; 1865adfc5217SJeff Kirsher mac_obj->get_cam_offset = bnx2x_get_cam_offset_mac; 1866adfc5217SJeff Kirsher mac_obj->put_cam_offset = bnx2x_put_cam_offset_mac; 1867adfc5217SJeff Kirsher 1868adfc5217SJeff Kirsher if (CHIP_IS_E1x(bp)) { 1869adfc5217SJeff Kirsher mac_obj->set_one_rule = bnx2x_set_one_mac_e1x; 1870adfc5217SJeff Kirsher mac_obj->check_del = bnx2x_check_mac_del; 1871adfc5217SJeff Kirsher mac_obj->check_add = bnx2x_check_mac_add; 1872adfc5217SJeff Kirsher mac_obj->check_move = bnx2x_check_move_always_err; 1873adfc5217SJeff Kirsher mac_obj->ramrod_cmd = RAMROD_CMD_ID_ETH_SET_MAC; 1874adfc5217SJeff Kirsher 1875adfc5217SJeff Kirsher /* Exe Queue */ 1876adfc5217SJeff Kirsher bnx2x_exe_queue_init(bp, 1877adfc5217SJeff Kirsher &mac_obj->exe_queue, 1, qable_obj, 1878adfc5217SJeff Kirsher bnx2x_validate_vlan_mac, 1879adfc5217SJeff Kirsher bnx2x_optimize_vlan_mac, 1880adfc5217SJeff Kirsher bnx2x_execute_vlan_mac, 1881adfc5217SJeff Kirsher bnx2x_exeq_get_mac); 1882adfc5217SJeff Kirsher } else { 1883adfc5217SJeff Kirsher mac_obj->set_one_rule = bnx2x_set_one_mac_e2; 1884adfc5217SJeff Kirsher mac_obj->check_del = bnx2x_check_mac_del; 1885adfc5217SJeff Kirsher mac_obj->check_add = bnx2x_check_mac_add; 1886adfc5217SJeff Kirsher mac_obj->check_move = bnx2x_check_move; 1887adfc5217SJeff Kirsher mac_obj->ramrod_cmd = 1888adfc5217SJeff Kirsher RAMROD_CMD_ID_ETH_CLASSIFICATION_RULES; 1889adfc5217SJeff Kirsher 1890adfc5217SJeff Kirsher /* Exe Queue */ 1891adfc5217SJeff Kirsher bnx2x_exe_queue_init(bp, 1892adfc5217SJeff Kirsher &mac_obj->exe_queue, CLASSIFY_RULES_COUNT, 1893adfc5217SJeff Kirsher qable_obj, bnx2x_validate_vlan_mac, 1894adfc5217SJeff Kirsher bnx2x_optimize_vlan_mac, 1895adfc5217SJeff Kirsher bnx2x_execute_vlan_mac, 1896adfc5217SJeff Kirsher bnx2x_exeq_get_mac); 1897adfc5217SJeff Kirsher } 1898adfc5217SJeff Kirsher } 1899adfc5217SJeff Kirsher 1900adfc5217SJeff Kirsher void bnx2x_init_vlan_obj(struct bnx2x *bp, 1901adfc5217SJeff Kirsher struct bnx2x_vlan_mac_obj *vlan_obj, 1902adfc5217SJeff Kirsher u8 cl_id, u32 cid, u8 func_id, void *rdata, 1903adfc5217SJeff Kirsher dma_addr_t rdata_mapping, int state, 1904adfc5217SJeff Kirsher unsigned long *pstate, bnx2x_obj_type type, 1905adfc5217SJeff Kirsher struct bnx2x_credit_pool_obj *vlans_pool) 1906adfc5217SJeff Kirsher { 1907adfc5217SJeff Kirsher union bnx2x_qable_obj *qable_obj = (union bnx2x_qable_obj *)vlan_obj; 1908adfc5217SJeff Kirsher 1909adfc5217SJeff Kirsher bnx2x_init_vlan_mac_common(vlan_obj, cl_id, cid, func_id, rdata, 1910adfc5217SJeff Kirsher rdata_mapping, state, pstate, type, NULL, 1911adfc5217SJeff Kirsher vlans_pool); 1912adfc5217SJeff Kirsher 1913adfc5217SJeff Kirsher vlan_obj->get_credit = bnx2x_get_credit_vlan; 1914adfc5217SJeff Kirsher vlan_obj->put_credit = bnx2x_put_credit_vlan; 1915adfc5217SJeff Kirsher vlan_obj->get_cam_offset = bnx2x_get_cam_offset_vlan; 1916adfc5217SJeff Kirsher vlan_obj->put_cam_offset = bnx2x_put_cam_offset_vlan; 1917adfc5217SJeff Kirsher 1918adfc5217SJeff Kirsher if (CHIP_IS_E1x(bp)) { 1919adfc5217SJeff Kirsher BNX2X_ERR("Do not support chips others than E2 and newer\n"); 1920adfc5217SJeff Kirsher BUG(); 1921adfc5217SJeff Kirsher } else { 1922adfc5217SJeff Kirsher vlan_obj->set_one_rule = bnx2x_set_one_vlan_e2; 1923adfc5217SJeff Kirsher vlan_obj->check_del = bnx2x_check_vlan_del; 1924adfc5217SJeff Kirsher vlan_obj->check_add = bnx2x_check_vlan_add; 1925adfc5217SJeff Kirsher vlan_obj->check_move = bnx2x_check_move; 1926adfc5217SJeff Kirsher vlan_obj->ramrod_cmd = 1927adfc5217SJeff Kirsher RAMROD_CMD_ID_ETH_CLASSIFICATION_RULES; 1928adfc5217SJeff Kirsher 1929adfc5217SJeff Kirsher /* Exe Queue */ 1930adfc5217SJeff Kirsher bnx2x_exe_queue_init(bp, 1931adfc5217SJeff Kirsher &vlan_obj->exe_queue, CLASSIFY_RULES_COUNT, 1932adfc5217SJeff Kirsher qable_obj, bnx2x_validate_vlan_mac, 1933adfc5217SJeff Kirsher bnx2x_optimize_vlan_mac, 1934adfc5217SJeff Kirsher bnx2x_execute_vlan_mac, 1935adfc5217SJeff Kirsher bnx2x_exeq_get_vlan); 1936adfc5217SJeff Kirsher } 1937adfc5217SJeff Kirsher } 1938adfc5217SJeff Kirsher 1939adfc5217SJeff Kirsher void bnx2x_init_vlan_mac_obj(struct bnx2x *bp, 1940adfc5217SJeff Kirsher struct bnx2x_vlan_mac_obj *vlan_mac_obj, 1941adfc5217SJeff Kirsher u8 cl_id, u32 cid, u8 func_id, void *rdata, 1942adfc5217SJeff Kirsher dma_addr_t rdata_mapping, int state, 1943adfc5217SJeff Kirsher unsigned long *pstate, bnx2x_obj_type type, 1944adfc5217SJeff Kirsher struct bnx2x_credit_pool_obj *macs_pool, 1945adfc5217SJeff Kirsher struct bnx2x_credit_pool_obj *vlans_pool) 1946adfc5217SJeff Kirsher { 1947adfc5217SJeff Kirsher union bnx2x_qable_obj *qable_obj = 1948adfc5217SJeff Kirsher (union bnx2x_qable_obj *)vlan_mac_obj; 1949adfc5217SJeff Kirsher 1950adfc5217SJeff Kirsher bnx2x_init_vlan_mac_common(vlan_mac_obj, cl_id, cid, func_id, rdata, 1951adfc5217SJeff Kirsher rdata_mapping, state, pstate, type, 1952adfc5217SJeff Kirsher macs_pool, vlans_pool); 1953adfc5217SJeff Kirsher 1954adfc5217SJeff Kirsher /* CAM pool handling */ 1955adfc5217SJeff Kirsher vlan_mac_obj->get_credit = bnx2x_get_credit_vlan_mac; 1956adfc5217SJeff Kirsher vlan_mac_obj->put_credit = bnx2x_put_credit_vlan_mac; 1957adfc5217SJeff Kirsher /* 1958adfc5217SJeff Kirsher * CAM offset is relevant for 57710 and 57711 chips only which have a 1959adfc5217SJeff Kirsher * single CAM for both MACs and VLAN-MAC pairs. So the offset 1960adfc5217SJeff Kirsher * will be taken from MACs' pool object only. 1961adfc5217SJeff Kirsher */ 1962adfc5217SJeff Kirsher vlan_mac_obj->get_cam_offset = bnx2x_get_cam_offset_mac; 1963adfc5217SJeff Kirsher vlan_mac_obj->put_cam_offset = bnx2x_put_cam_offset_mac; 1964adfc5217SJeff Kirsher 1965adfc5217SJeff Kirsher if (CHIP_IS_E1(bp)) { 1966adfc5217SJeff Kirsher BNX2X_ERR("Do not support chips others than E2\n"); 1967adfc5217SJeff Kirsher BUG(); 1968adfc5217SJeff Kirsher } else if (CHIP_IS_E1H(bp)) { 1969adfc5217SJeff Kirsher vlan_mac_obj->set_one_rule = bnx2x_set_one_vlan_mac_e1h; 1970adfc5217SJeff Kirsher vlan_mac_obj->check_del = bnx2x_check_vlan_mac_del; 1971adfc5217SJeff Kirsher vlan_mac_obj->check_add = bnx2x_check_vlan_mac_add; 1972adfc5217SJeff Kirsher vlan_mac_obj->check_move = bnx2x_check_move_always_err; 1973adfc5217SJeff Kirsher vlan_mac_obj->ramrod_cmd = RAMROD_CMD_ID_ETH_SET_MAC; 1974adfc5217SJeff Kirsher 1975adfc5217SJeff Kirsher /* Exe Queue */ 1976adfc5217SJeff Kirsher bnx2x_exe_queue_init(bp, 1977adfc5217SJeff Kirsher &vlan_mac_obj->exe_queue, 1, qable_obj, 1978adfc5217SJeff Kirsher bnx2x_validate_vlan_mac, 1979adfc5217SJeff Kirsher bnx2x_optimize_vlan_mac, 1980adfc5217SJeff Kirsher bnx2x_execute_vlan_mac, 1981adfc5217SJeff Kirsher bnx2x_exeq_get_vlan_mac); 1982adfc5217SJeff Kirsher } else { 1983adfc5217SJeff Kirsher vlan_mac_obj->set_one_rule = bnx2x_set_one_vlan_mac_e2; 1984adfc5217SJeff Kirsher vlan_mac_obj->check_del = bnx2x_check_vlan_mac_del; 1985adfc5217SJeff Kirsher vlan_mac_obj->check_add = bnx2x_check_vlan_mac_add; 1986adfc5217SJeff Kirsher vlan_mac_obj->check_move = bnx2x_check_move; 1987adfc5217SJeff Kirsher vlan_mac_obj->ramrod_cmd = 1988adfc5217SJeff Kirsher RAMROD_CMD_ID_ETH_CLASSIFICATION_RULES; 1989adfc5217SJeff Kirsher 1990adfc5217SJeff Kirsher /* Exe Queue */ 1991adfc5217SJeff Kirsher bnx2x_exe_queue_init(bp, 1992adfc5217SJeff Kirsher &vlan_mac_obj->exe_queue, 1993adfc5217SJeff Kirsher CLASSIFY_RULES_COUNT, 1994adfc5217SJeff Kirsher qable_obj, bnx2x_validate_vlan_mac, 1995adfc5217SJeff Kirsher bnx2x_optimize_vlan_mac, 1996adfc5217SJeff Kirsher bnx2x_execute_vlan_mac, 1997adfc5217SJeff Kirsher bnx2x_exeq_get_vlan_mac); 1998adfc5217SJeff Kirsher } 1999adfc5217SJeff Kirsher 2000adfc5217SJeff Kirsher } 2001adfc5217SJeff Kirsher 2002adfc5217SJeff Kirsher /* RX_MODE verbs: DROP_ALL/ACCEPT_ALL/ACCEPT_ALL_MULTI/ACCEPT_ALL_VLAN/NORMAL */ 2003adfc5217SJeff Kirsher static inline void __storm_memset_mac_filters(struct bnx2x *bp, 2004adfc5217SJeff Kirsher struct tstorm_eth_mac_filter_config *mac_filters, 2005adfc5217SJeff Kirsher u16 pf_id) 2006adfc5217SJeff Kirsher { 2007adfc5217SJeff Kirsher size_t size = sizeof(struct tstorm_eth_mac_filter_config); 2008adfc5217SJeff Kirsher 2009adfc5217SJeff Kirsher u32 addr = BAR_TSTRORM_INTMEM + 2010adfc5217SJeff Kirsher TSTORM_MAC_FILTER_CONFIG_OFFSET(pf_id); 2011adfc5217SJeff Kirsher 2012adfc5217SJeff Kirsher __storm_memset_struct(bp, addr, size, (u32 *)mac_filters); 2013adfc5217SJeff Kirsher } 2014adfc5217SJeff Kirsher 2015adfc5217SJeff Kirsher static int bnx2x_set_rx_mode_e1x(struct bnx2x *bp, 2016adfc5217SJeff Kirsher struct bnx2x_rx_mode_ramrod_params *p) 2017adfc5217SJeff Kirsher { 2018adfc5217SJeff Kirsher /* update the bp MAC filter structure */ 2019adfc5217SJeff Kirsher u32 mask = (1 << p->cl_id); 2020adfc5217SJeff Kirsher 2021adfc5217SJeff Kirsher struct tstorm_eth_mac_filter_config *mac_filters = 2022adfc5217SJeff Kirsher (struct tstorm_eth_mac_filter_config *)p->rdata; 2023adfc5217SJeff Kirsher 2024adfc5217SJeff Kirsher /* initial seeting is drop-all */ 2025adfc5217SJeff Kirsher u8 drop_all_ucast = 1, drop_all_mcast = 1; 2026adfc5217SJeff Kirsher u8 accp_all_ucast = 0, accp_all_bcast = 0, accp_all_mcast = 0; 2027adfc5217SJeff Kirsher u8 unmatched_unicast = 0; 2028adfc5217SJeff Kirsher 2029adfc5217SJeff Kirsher /* In e1x there we only take into account rx acceot flag since tx switching 2030adfc5217SJeff Kirsher * isn't enabled. */ 2031adfc5217SJeff Kirsher if (test_bit(BNX2X_ACCEPT_UNICAST, &p->rx_accept_flags)) 2032adfc5217SJeff Kirsher /* accept matched ucast */ 2033adfc5217SJeff Kirsher drop_all_ucast = 0; 2034adfc5217SJeff Kirsher 2035adfc5217SJeff Kirsher if (test_bit(BNX2X_ACCEPT_MULTICAST, &p->rx_accept_flags)) 2036adfc5217SJeff Kirsher /* accept matched mcast */ 2037adfc5217SJeff Kirsher drop_all_mcast = 0; 2038adfc5217SJeff Kirsher 2039adfc5217SJeff Kirsher if (test_bit(BNX2X_ACCEPT_ALL_UNICAST, &p->rx_accept_flags)) { 2040adfc5217SJeff Kirsher /* accept all mcast */ 2041adfc5217SJeff Kirsher drop_all_ucast = 0; 2042adfc5217SJeff Kirsher accp_all_ucast = 1; 2043adfc5217SJeff Kirsher } 2044adfc5217SJeff Kirsher if (test_bit(BNX2X_ACCEPT_ALL_MULTICAST, &p->rx_accept_flags)) { 2045adfc5217SJeff Kirsher /* accept all mcast */ 2046adfc5217SJeff Kirsher drop_all_mcast = 0; 2047adfc5217SJeff Kirsher accp_all_mcast = 1; 2048adfc5217SJeff Kirsher } 2049adfc5217SJeff Kirsher if (test_bit(BNX2X_ACCEPT_BROADCAST, &p->rx_accept_flags)) 2050adfc5217SJeff Kirsher /* accept (all) bcast */ 2051adfc5217SJeff Kirsher accp_all_bcast = 1; 2052adfc5217SJeff Kirsher if (test_bit(BNX2X_ACCEPT_UNMATCHED, &p->rx_accept_flags)) 2053adfc5217SJeff Kirsher /* accept unmatched unicasts */ 2054adfc5217SJeff Kirsher unmatched_unicast = 1; 2055adfc5217SJeff Kirsher 2056adfc5217SJeff Kirsher mac_filters->ucast_drop_all = drop_all_ucast ? 2057adfc5217SJeff Kirsher mac_filters->ucast_drop_all | mask : 2058adfc5217SJeff Kirsher mac_filters->ucast_drop_all & ~mask; 2059adfc5217SJeff Kirsher 2060adfc5217SJeff Kirsher mac_filters->mcast_drop_all = drop_all_mcast ? 2061adfc5217SJeff Kirsher mac_filters->mcast_drop_all | mask : 2062adfc5217SJeff Kirsher mac_filters->mcast_drop_all & ~mask; 2063adfc5217SJeff Kirsher 2064adfc5217SJeff Kirsher mac_filters->ucast_accept_all = accp_all_ucast ? 2065adfc5217SJeff Kirsher mac_filters->ucast_accept_all | mask : 2066adfc5217SJeff Kirsher mac_filters->ucast_accept_all & ~mask; 2067adfc5217SJeff Kirsher 2068adfc5217SJeff Kirsher mac_filters->mcast_accept_all = accp_all_mcast ? 2069adfc5217SJeff Kirsher mac_filters->mcast_accept_all | mask : 2070adfc5217SJeff Kirsher mac_filters->mcast_accept_all & ~mask; 2071adfc5217SJeff Kirsher 2072adfc5217SJeff Kirsher mac_filters->bcast_accept_all = accp_all_bcast ? 2073adfc5217SJeff Kirsher mac_filters->bcast_accept_all | mask : 2074adfc5217SJeff Kirsher mac_filters->bcast_accept_all & ~mask; 2075adfc5217SJeff Kirsher 2076adfc5217SJeff Kirsher mac_filters->unmatched_unicast = unmatched_unicast ? 2077adfc5217SJeff Kirsher mac_filters->unmatched_unicast | mask : 2078adfc5217SJeff Kirsher mac_filters->unmatched_unicast & ~mask; 2079adfc5217SJeff Kirsher 2080adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "drop_ucast 0x%x\ndrop_mcast 0x%x\n accp_ucast 0x%x\n" 2081adfc5217SJeff Kirsher "accp_mcast 0x%x\naccp_bcast 0x%x\n", 2082adfc5217SJeff Kirsher mac_filters->ucast_drop_all, 2083adfc5217SJeff Kirsher mac_filters->mcast_drop_all, 2084adfc5217SJeff Kirsher mac_filters->ucast_accept_all, 2085adfc5217SJeff Kirsher mac_filters->mcast_accept_all, 2086adfc5217SJeff Kirsher mac_filters->bcast_accept_all); 2087adfc5217SJeff Kirsher 2088adfc5217SJeff Kirsher /* write the MAC filter structure*/ 2089adfc5217SJeff Kirsher __storm_memset_mac_filters(bp, mac_filters, p->func_id); 2090adfc5217SJeff Kirsher 2091adfc5217SJeff Kirsher /* The operation is completed */ 2092adfc5217SJeff Kirsher clear_bit(p->state, p->pstate); 2093adfc5217SJeff Kirsher smp_mb__after_clear_bit(); 2094adfc5217SJeff Kirsher 2095adfc5217SJeff Kirsher return 0; 2096adfc5217SJeff Kirsher } 2097adfc5217SJeff Kirsher 2098adfc5217SJeff Kirsher /* Setup ramrod data */ 2099adfc5217SJeff Kirsher static inline void bnx2x_rx_mode_set_rdata_hdr_e2(u32 cid, 2100adfc5217SJeff Kirsher struct eth_classify_header *hdr, 2101adfc5217SJeff Kirsher u8 rule_cnt) 2102adfc5217SJeff Kirsher { 2103adfc5217SJeff Kirsher hdr->echo = cid; 2104adfc5217SJeff Kirsher hdr->rule_cnt = rule_cnt; 2105adfc5217SJeff Kirsher } 2106adfc5217SJeff Kirsher 2107adfc5217SJeff Kirsher static inline void bnx2x_rx_mode_set_cmd_state_e2(struct bnx2x *bp, 2108adfc5217SJeff Kirsher unsigned long accept_flags, 2109adfc5217SJeff Kirsher struct eth_filter_rules_cmd *cmd, 2110adfc5217SJeff Kirsher bool clear_accept_all) 2111adfc5217SJeff Kirsher { 2112adfc5217SJeff Kirsher u16 state; 2113adfc5217SJeff Kirsher 2114adfc5217SJeff Kirsher /* start with 'drop-all' */ 2115adfc5217SJeff Kirsher state = ETH_FILTER_RULES_CMD_UCAST_DROP_ALL | 2116adfc5217SJeff Kirsher ETH_FILTER_RULES_CMD_MCAST_DROP_ALL; 2117adfc5217SJeff Kirsher 2118adfc5217SJeff Kirsher if (accept_flags) { 2119adfc5217SJeff Kirsher if (test_bit(BNX2X_ACCEPT_UNICAST, &accept_flags)) 2120adfc5217SJeff Kirsher state &= ~ETH_FILTER_RULES_CMD_UCAST_DROP_ALL; 2121adfc5217SJeff Kirsher 2122adfc5217SJeff Kirsher if (test_bit(BNX2X_ACCEPT_MULTICAST, &accept_flags)) 2123adfc5217SJeff Kirsher state &= ~ETH_FILTER_RULES_CMD_MCAST_DROP_ALL; 2124adfc5217SJeff Kirsher 2125adfc5217SJeff Kirsher if (test_bit(BNX2X_ACCEPT_ALL_UNICAST, &accept_flags)) { 2126adfc5217SJeff Kirsher state &= ~ETH_FILTER_RULES_CMD_UCAST_DROP_ALL; 2127adfc5217SJeff Kirsher state |= ETH_FILTER_RULES_CMD_UCAST_ACCEPT_ALL; 2128adfc5217SJeff Kirsher } 2129adfc5217SJeff Kirsher 2130adfc5217SJeff Kirsher if (test_bit(BNX2X_ACCEPT_ALL_MULTICAST, &accept_flags)) { 2131adfc5217SJeff Kirsher state |= ETH_FILTER_RULES_CMD_MCAST_ACCEPT_ALL; 2132adfc5217SJeff Kirsher state &= ~ETH_FILTER_RULES_CMD_MCAST_DROP_ALL; 2133adfc5217SJeff Kirsher } 2134adfc5217SJeff Kirsher if (test_bit(BNX2X_ACCEPT_BROADCAST, &accept_flags)) 2135adfc5217SJeff Kirsher state |= ETH_FILTER_RULES_CMD_BCAST_ACCEPT_ALL; 2136adfc5217SJeff Kirsher 2137adfc5217SJeff Kirsher if (test_bit(BNX2X_ACCEPT_UNMATCHED, &accept_flags)) { 2138adfc5217SJeff Kirsher state &= ~ETH_FILTER_RULES_CMD_UCAST_DROP_ALL; 2139adfc5217SJeff Kirsher state |= ETH_FILTER_RULES_CMD_UCAST_ACCEPT_UNMATCHED; 2140adfc5217SJeff Kirsher } 2141adfc5217SJeff Kirsher if (test_bit(BNX2X_ACCEPT_ANY_VLAN, &accept_flags)) 2142adfc5217SJeff Kirsher state |= ETH_FILTER_RULES_CMD_ACCEPT_ANY_VLAN; 2143adfc5217SJeff Kirsher } 2144adfc5217SJeff Kirsher 2145adfc5217SJeff Kirsher /* Clear ACCEPT_ALL_XXX flags for FCoE L2 Queue */ 2146adfc5217SJeff Kirsher if (clear_accept_all) { 2147adfc5217SJeff Kirsher state &= ~ETH_FILTER_RULES_CMD_MCAST_ACCEPT_ALL; 2148adfc5217SJeff Kirsher state &= ~ETH_FILTER_RULES_CMD_BCAST_ACCEPT_ALL; 2149adfc5217SJeff Kirsher state &= ~ETH_FILTER_RULES_CMD_UCAST_ACCEPT_ALL; 2150adfc5217SJeff Kirsher state &= ~ETH_FILTER_RULES_CMD_UCAST_ACCEPT_UNMATCHED; 2151adfc5217SJeff Kirsher } 2152adfc5217SJeff Kirsher 2153adfc5217SJeff Kirsher cmd->state = cpu_to_le16(state); 2154adfc5217SJeff Kirsher 2155adfc5217SJeff Kirsher } 2156adfc5217SJeff Kirsher 2157adfc5217SJeff Kirsher static int bnx2x_set_rx_mode_e2(struct bnx2x *bp, 2158adfc5217SJeff Kirsher struct bnx2x_rx_mode_ramrod_params *p) 2159adfc5217SJeff Kirsher { 2160adfc5217SJeff Kirsher struct eth_filter_rules_ramrod_data *data = p->rdata; 2161adfc5217SJeff Kirsher int rc; 2162adfc5217SJeff Kirsher u8 rule_idx = 0; 2163adfc5217SJeff Kirsher 2164adfc5217SJeff Kirsher /* Reset the ramrod data buffer */ 2165adfc5217SJeff Kirsher memset(data, 0, sizeof(*data)); 2166adfc5217SJeff Kirsher 2167adfc5217SJeff Kirsher /* Setup ramrod data */ 2168adfc5217SJeff Kirsher 2169adfc5217SJeff Kirsher /* Tx (internal switching) */ 2170adfc5217SJeff Kirsher if (test_bit(RAMROD_TX, &p->ramrod_flags)) { 2171adfc5217SJeff Kirsher data->rules[rule_idx].client_id = p->cl_id; 2172adfc5217SJeff Kirsher data->rules[rule_idx].func_id = p->func_id; 2173adfc5217SJeff Kirsher 2174adfc5217SJeff Kirsher data->rules[rule_idx].cmd_general_data = 2175adfc5217SJeff Kirsher ETH_FILTER_RULES_CMD_TX_CMD; 2176adfc5217SJeff Kirsher 2177adfc5217SJeff Kirsher bnx2x_rx_mode_set_cmd_state_e2(bp, p->tx_accept_flags, 2178adfc5217SJeff Kirsher &(data->rules[rule_idx++]), false); 2179adfc5217SJeff Kirsher } 2180adfc5217SJeff Kirsher 2181adfc5217SJeff Kirsher /* Rx */ 2182adfc5217SJeff Kirsher if (test_bit(RAMROD_RX, &p->ramrod_flags)) { 2183adfc5217SJeff Kirsher data->rules[rule_idx].client_id = p->cl_id; 2184adfc5217SJeff Kirsher data->rules[rule_idx].func_id = p->func_id; 2185adfc5217SJeff Kirsher 2186adfc5217SJeff Kirsher data->rules[rule_idx].cmd_general_data = 2187adfc5217SJeff Kirsher ETH_FILTER_RULES_CMD_RX_CMD; 2188adfc5217SJeff Kirsher 2189adfc5217SJeff Kirsher bnx2x_rx_mode_set_cmd_state_e2(bp, p->rx_accept_flags, 2190adfc5217SJeff Kirsher &(data->rules[rule_idx++]), false); 2191adfc5217SJeff Kirsher } 2192adfc5217SJeff Kirsher 2193adfc5217SJeff Kirsher 2194adfc5217SJeff Kirsher /* 2195adfc5217SJeff Kirsher * If FCoE Queue configuration has been requested configure the Rx and 2196adfc5217SJeff Kirsher * internal switching modes for this queue in separate rules. 2197adfc5217SJeff Kirsher * 2198adfc5217SJeff Kirsher * FCoE queue shell never be set to ACCEPT_ALL packets of any sort: 2199adfc5217SJeff Kirsher * MCAST_ALL, UCAST_ALL, BCAST_ALL and UNMATCHED. 2200adfc5217SJeff Kirsher */ 2201adfc5217SJeff Kirsher if (test_bit(BNX2X_RX_MODE_FCOE_ETH, &p->rx_mode_flags)) { 2202adfc5217SJeff Kirsher /* Tx (internal switching) */ 2203adfc5217SJeff Kirsher if (test_bit(RAMROD_TX, &p->ramrod_flags)) { 2204adfc5217SJeff Kirsher data->rules[rule_idx].client_id = bnx2x_fcoe(bp, cl_id); 2205adfc5217SJeff Kirsher data->rules[rule_idx].func_id = p->func_id; 2206adfc5217SJeff Kirsher 2207adfc5217SJeff Kirsher data->rules[rule_idx].cmd_general_data = 2208adfc5217SJeff Kirsher ETH_FILTER_RULES_CMD_TX_CMD; 2209adfc5217SJeff Kirsher 2210adfc5217SJeff Kirsher bnx2x_rx_mode_set_cmd_state_e2(bp, p->tx_accept_flags, 2211adfc5217SJeff Kirsher &(data->rules[rule_idx++]), 2212adfc5217SJeff Kirsher true); 2213adfc5217SJeff Kirsher } 2214adfc5217SJeff Kirsher 2215adfc5217SJeff Kirsher /* Rx */ 2216adfc5217SJeff Kirsher if (test_bit(RAMROD_RX, &p->ramrod_flags)) { 2217adfc5217SJeff Kirsher data->rules[rule_idx].client_id = bnx2x_fcoe(bp, cl_id); 2218adfc5217SJeff Kirsher data->rules[rule_idx].func_id = p->func_id; 2219adfc5217SJeff Kirsher 2220adfc5217SJeff Kirsher data->rules[rule_idx].cmd_general_data = 2221adfc5217SJeff Kirsher ETH_FILTER_RULES_CMD_RX_CMD; 2222adfc5217SJeff Kirsher 2223adfc5217SJeff Kirsher bnx2x_rx_mode_set_cmd_state_e2(bp, p->rx_accept_flags, 2224adfc5217SJeff Kirsher &(data->rules[rule_idx++]), 2225adfc5217SJeff Kirsher true); 2226adfc5217SJeff Kirsher } 2227adfc5217SJeff Kirsher } 2228adfc5217SJeff Kirsher 2229adfc5217SJeff Kirsher /* 2230adfc5217SJeff Kirsher * Set the ramrod header (most importantly - number of rules to 2231adfc5217SJeff Kirsher * configure). 2232adfc5217SJeff Kirsher */ 2233adfc5217SJeff Kirsher bnx2x_rx_mode_set_rdata_hdr_e2(p->cid, &data->header, rule_idx); 2234adfc5217SJeff Kirsher 2235adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "About to configure %d rules, rx_accept_flags 0x%lx, " 2236adfc5217SJeff Kirsher "tx_accept_flags 0x%lx\n", 2237adfc5217SJeff Kirsher data->header.rule_cnt, p->rx_accept_flags, 2238adfc5217SJeff Kirsher p->tx_accept_flags); 2239adfc5217SJeff Kirsher 2240adfc5217SJeff Kirsher /* 2241adfc5217SJeff Kirsher * No need for an explicit memory barrier here as long we would 2242adfc5217SJeff Kirsher * need to ensure the ordering of writing to the SPQ element 2243adfc5217SJeff Kirsher * and updating of the SPQ producer which involves a memory 2244adfc5217SJeff Kirsher * read and we will have to put a full memory barrier there 2245adfc5217SJeff Kirsher * (inside bnx2x_sp_post()). 2246adfc5217SJeff Kirsher */ 2247adfc5217SJeff Kirsher 2248adfc5217SJeff Kirsher /* Send a ramrod */ 2249adfc5217SJeff Kirsher rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_FILTER_RULES, p->cid, 2250adfc5217SJeff Kirsher U64_HI(p->rdata_mapping), 2251adfc5217SJeff Kirsher U64_LO(p->rdata_mapping), 2252adfc5217SJeff Kirsher ETH_CONNECTION_TYPE); 2253adfc5217SJeff Kirsher if (rc) 2254adfc5217SJeff Kirsher return rc; 2255adfc5217SJeff Kirsher 2256adfc5217SJeff Kirsher /* Ramrod completion is pending */ 2257adfc5217SJeff Kirsher return 1; 2258adfc5217SJeff Kirsher } 2259adfc5217SJeff Kirsher 2260adfc5217SJeff Kirsher static int bnx2x_wait_rx_mode_comp_e2(struct bnx2x *bp, 2261adfc5217SJeff Kirsher struct bnx2x_rx_mode_ramrod_params *p) 2262adfc5217SJeff Kirsher { 2263adfc5217SJeff Kirsher return bnx2x_state_wait(bp, p->state, p->pstate); 2264adfc5217SJeff Kirsher } 2265adfc5217SJeff Kirsher 2266adfc5217SJeff Kirsher static int bnx2x_empty_rx_mode_wait(struct bnx2x *bp, 2267adfc5217SJeff Kirsher struct bnx2x_rx_mode_ramrod_params *p) 2268adfc5217SJeff Kirsher { 2269adfc5217SJeff Kirsher /* Do nothing */ 2270adfc5217SJeff Kirsher return 0; 2271adfc5217SJeff Kirsher } 2272adfc5217SJeff Kirsher 2273adfc5217SJeff Kirsher int bnx2x_config_rx_mode(struct bnx2x *bp, 2274adfc5217SJeff Kirsher struct bnx2x_rx_mode_ramrod_params *p) 2275adfc5217SJeff Kirsher { 2276adfc5217SJeff Kirsher int rc; 2277adfc5217SJeff Kirsher 2278adfc5217SJeff Kirsher /* Configure the new classification in the chip */ 2279adfc5217SJeff Kirsher rc = p->rx_mode_obj->config_rx_mode(bp, p); 2280adfc5217SJeff Kirsher if (rc < 0) 2281adfc5217SJeff Kirsher return rc; 2282adfc5217SJeff Kirsher 2283adfc5217SJeff Kirsher /* Wait for a ramrod completion if was requested */ 2284adfc5217SJeff Kirsher if (test_bit(RAMROD_COMP_WAIT, &p->ramrod_flags)) { 2285adfc5217SJeff Kirsher rc = p->rx_mode_obj->wait_comp(bp, p); 2286adfc5217SJeff Kirsher if (rc) 2287adfc5217SJeff Kirsher return rc; 2288adfc5217SJeff Kirsher } 2289adfc5217SJeff Kirsher 2290adfc5217SJeff Kirsher return rc; 2291adfc5217SJeff Kirsher } 2292adfc5217SJeff Kirsher 2293adfc5217SJeff Kirsher void bnx2x_init_rx_mode_obj(struct bnx2x *bp, 2294adfc5217SJeff Kirsher struct bnx2x_rx_mode_obj *o) 2295adfc5217SJeff Kirsher { 2296adfc5217SJeff Kirsher if (CHIP_IS_E1x(bp)) { 2297adfc5217SJeff Kirsher o->wait_comp = bnx2x_empty_rx_mode_wait; 2298adfc5217SJeff Kirsher o->config_rx_mode = bnx2x_set_rx_mode_e1x; 2299adfc5217SJeff Kirsher } else { 2300adfc5217SJeff Kirsher o->wait_comp = bnx2x_wait_rx_mode_comp_e2; 2301adfc5217SJeff Kirsher o->config_rx_mode = bnx2x_set_rx_mode_e2; 2302adfc5217SJeff Kirsher } 2303adfc5217SJeff Kirsher } 2304adfc5217SJeff Kirsher 2305adfc5217SJeff Kirsher /********************* Multicast verbs: SET, CLEAR ****************************/ 2306adfc5217SJeff Kirsher static inline u8 bnx2x_mcast_bin_from_mac(u8 *mac) 2307adfc5217SJeff Kirsher { 2308adfc5217SJeff Kirsher return (crc32c_le(0, mac, ETH_ALEN) >> 24) & 0xff; 2309adfc5217SJeff Kirsher } 2310adfc5217SJeff Kirsher 2311adfc5217SJeff Kirsher struct bnx2x_mcast_mac_elem { 2312adfc5217SJeff Kirsher struct list_head link; 2313adfc5217SJeff Kirsher u8 mac[ETH_ALEN]; 2314adfc5217SJeff Kirsher u8 pad[2]; /* For a natural alignment of the following buffer */ 2315adfc5217SJeff Kirsher }; 2316adfc5217SJeff Kirsher 2317adfc5217SJeff Kirsher struct bnx2x_pending_mcast_cmd { 2318adfc5217SJeff Kirsher struct list_head link; 2319adfc5217SJeff Kirsher int type; /* BNX2X_MCAST_CMD_X */ 2320adfc5217SJeff Kirsher union { 2321adfc5217SJeff Kirsher struct list_head macs_head; 2322adfc5217SJeff Kirsher u32 macs_num; /* Needed for DEL command */ 2323adfc5217SJeff Kirsher int next_bin; /* Needed for RESTORE flow with aprox match */ 2324adfc5217SJeff Kirsher } data; 2325adfc5217SJeff Kirsher 2326adfc5217SJeff Kirsher bool done; /* set to true, when the command has been handled, 2327adfc5217SJeff Kirsher * practically used in 57712 handling only, where one pending 2328adfc5217SJeff Kirsher * command may be handled in a few operations. As long as for 2329adfc5217SJeff Kirsher * other chips every operation handling is completed in a 2330adfc5217SJeff Kirsher * single ramrod, there is no need to utilize this field. 2331adfc5217SJeff Kirsher */ 2332adfc5217SJeff Kirsher }; 2333adfc5217SJeff Kirsher 2334adfc5217SJeff Kirsher static int bnx2x_mcast_wait(struct bnx2x *bp, 2335adfc5217SJeff Kirsher struct bnx2x_mcast_obj *o) 2336adfc5217SJeff Kirsher { 2337adfc5217SJeff Kirsher if (bnx2x_state_wait(bp, o->sched_state, o->raw.pstate) || 2338adfc5217SJeff Kirsher o->raw.wait_comp(bp, &o->raw)) 2339adfc5217SJeff Kirsher return -EBUSY; 2340adfc5217SJeff Kirsher 2341adfc5217SJeff Kirsher return 0; 2342adfc5217SJeff Kirsher } 2343adfc5217SJeff Kirsher 2344adfc5217SJeff Kirsher static int bnx2x_mcast_enqueue_cmd(struct bnx2x *bp, 2345adfc5217SJeff Kirsher struct bnx2x_mcast_obj *o, 2346adfc5217SJeff Kirsher struct bnx2x_mcast_ramrod_params *p, 2347adfc5217SJeff Kirsher int cmd) 2348adfc5217SJeff Kirsher { 2349adfc5217SJeff Kirsher int total_sz; 2350adfc5217SJeff Kirsher struct bnx2x_pending_mcast_cmd *new_cmd; 2351adfc5217SJeff Kirsher struct bnx2x_mcast_mac_elem *cur_mac = NULL; 2352adfc5217SJeff Kirsher struct bnx2x_mcast_list_elem *pos; 2353adfc5217SJeff Kirsher int macs_list_len = ((cmd == BNX2X_MCAST_CMD_ADD) ? 2354adfc5217SJeff Kirsher p->mcast_list_len : 0); 2355adfc5217SJeff Kirsher 2356adfc5217SJeff Kirsher /* If the command is empty ("handle pending commands only"), break */ 2357adfc5217SJeff Kirsher if (!p->mcast_list_len) 2358adfc5217SJeff Kirsher return 0; 2359adfc5217SJeff Kirsher 2360adfc5217SJeff Kirsher total_sz = sizeof(*new_cmd) + 2361adfc5217SJeff Kirsher macs_list_len * sizeof(struct bnx2x_mcast_mac_elem); 2362adfc5217SJeff Kirsher 2363adfc5217SJeff Kirsher /* Add mcast is called under spin_lock, thus calling with GFP_ATOMIC */ 2364adfc5217SJeff Kirsher new_cmd = kzalloc(total_sz, GFP_ATOMIC); 2365adfc5217SJeff Kirsher 2366adfc5217SJeff Kirsher if (!new_cmd) 2367adfc5217SJeff Kirsher return -ENOMEM; 2368adfc5217SJeff Kirsher 2369adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "About to enqueue a new %d command. " 2370adfc5217SJeff Kirsher "macs_list_len=%d\n", cmd, macs_list_len); 2371adfc5217SJeff Kirsher 2372adfc5217SJeff Kirsher INIT_LIST_HEAD(&new_cmd->data.macs_head); 2373adfc5217SJeff Kirsher 2374adfc5217SJeff Kirsher new_cmd->type = cmd; 2375adfc5217SJeff Kirsher new_cmd->done = false; 2376adfc5217SJeff Kirsher 2377adfc5217SJeff Kirsher switch (cmd) { 2378adfc5217SJeff Kirsher case BNX2X_MCAST_CMD_ADD: 2379adfc5217SJeff Kirsher cur_mac = (struct bnx2x_mcast_mac_elem *) 2380adfc5217SJeff Kirsher ((u8 *)new_cmd + sizeof(*new_cmd)); 2381adfc5217SJeff Kirsher 2382adfc5217SJeff Kirsher /* Push the MACs of the current command into the pendig command 2383adfc5217SJeff Kirsher * MACs list: FIFO 2384adfc5217SJeff Kirsher */ 2385adfc5217SJeff Kirsher list_for_each_entry(pos, &p->mcast_list, link) { 2386adfc5217SJeff Kirsher memcpy(cur_mac->mac, pos->mac, ETH_ALEN); 2387adfc5217SJeff Kirsher list_add_tail(&cur_mac->link, &new_cmd->data.macs_head); 2388adfc5217SJeff Kirsher cur_mac++; 2389adfc5217SJeff Kirsher } 2390adfc5217SJeff Kirsher 2391adfc5217SJeff Kirsher break; 2392adfc5217SJeff Kirsher 2393adfc5217SJeff Kirsher case BNX2X_MCAST_CMD_DEL: 2394adfc5217SJeff Kirsher new_cmd->data.macs_num = p->mcast_list_len; 2395adfc5217SJeff Kirsher break; 2396adfc5217SJeff Kirsher 2397adfc5217SJeff Kirsher case BNX2X_MCAST_CMD_RESTORE: 2398adfc5217SJeff Kirsher new_cmd->data.next_bin = 0; 2399adfc5217SJeff Kirsher break; 2400adfc5217SJeff Kirsher 2401adfc5217SJeff Kirsher default: 2402adfc5217SJeff Kirsher BNX2X_ERR("Unknown command: %d\n", cmd); 2403adfc5217SJeff Kirsher return -EINVAL; 2404adfc5217SJeff Kirsher } 2405adfc5217SJeff Kirsher 2406adfc5217SJeff Kirsher /* Push the new pending command to the tail of the pending list: FIFO */ 2407adfc5217SJeff Kirsher list_add_tail(&new_cmd->link, &o->pending_cmds_head); 2408adfc5217SJeff Kirsher 2409adfc5217SJeff Kirsher o->set_sched(o); 2410adfc5217SJeff Kirsher 2411adfc5217SJeff Kirsher return 1; 2412adfc5217SJeff Kirsher } 2413adfc5217SJeff Kirsher 2414adfc5217SJeff Kirsher /** 2415adfc5217SJeff Kirsher * bnx2x_mcast_get_next_bin - get the next set bin (index) 2416adfc5217SJeff Kirsher * 2417adfc5217SJeff Kirsher * @o: 2418adfc5217SJeff Kirsher * @last: index to start looking from (including) 2419adfc5217SJeff Kirsher * 2420adfc5217SJeff Kirsher * returns the next found (set) bin or a negative value if none is found. 2421adfc5217SJeff Kirsher */ 2422adfc5217SJeff Kirsher static inline int bnx2x_mcast_get_next_bin(struct bnx2x_mcast_obj *o, int last) 2423adfc5217SJeff Kirsher { 2424adfc5217SJeff Kirsher int i, j, inner_start = last % BIT_VEC64_ELEM_SZ; 2425adfc5217SJeff Kirsher 2426adfc5217SJeff Kirsher for (i = last / BIT_VEC64_ELEM_SZ; i < BNX2X_MCAST_VEC_SZ; i++) { 2427adfc5217SJeff Kirsher if (o->registry.aprox_match.vec[i]) 2428adfc5217SJeff Kirsher for (j = inner_start; j < BIT_VEC64_ELEM_SZ; j++) { 2429adfc5217SJeff Kirsher int cur_bit = j + BIT_VEC64_ELEM_SZ * i; 2430adfc5217SJeff Kirsher if (BIT_VEC64_TEST_BIT(o->registry.aprox_match. 2431adfc5217SJeff Kirsher vec, cur_bit)) { 2432adfc5217SJeff Kirsher return cur_bit; 2433adfc5217SJeff Kirsher } 2434adfc5217SJeff Kirsher } 2435adfc5217SJeff Kirsher inner_start = 0; 2436adfc5217SJeff Kirsher } 2437adfc5217SJeff Kirsher 2438adfc5217SJeff Kirsher /* None found */ 2439adfc5217SJeff Kirsher return -1; 2440adfc5217SJeff Kirsher } 2441adfc5217SJeff Kirsher 2442adfc5217SJeff Kirsher /** 2443adfc5217SJeff Kirsher * bnx2x_mcast_clear_first_bin - find the first set bin and clear it 2444adfc5217SJeff Kirsher * 2445adfc5217SJeff Kirsher * @o: 2446adfc5217SJeff Kirsher * 2447adfc5217SJeff Kirsher * returns the index of the found bin or -1 if none is found 2448adfc5217SJeff Kirsher */ 2449adfc5217SJeff Kirsher static inline int bnx2x_mcast_clear_first_bin(struct bnx2x_mcast_obj *o) 2450adfc5217SJeff Kirsher { 2451adfc5217SJeff Kirsher int cur_bit = bnx2x_mcast_get_next_bin(o, 0); 2452adfc5217SJeff Kirsher 2453adfc5217SJeff Kirsher if (cur_bit >= 0) 2454adfc5217SJeff Kirsher BIT_VEC64_CLEAR_BIT(o->registry.aprox_match.vec, cur_bit); 2455adfc5217SJeff Kirsher 2456adfc5217SJeff Kirsher return cur_bit; 2457adfc5217SJeff Kirsher } 2458adfc5217SJeff Kirsher 2459adfc5217SJeff Kirsher static inline u8 bnx2x_mcast_get_rx_tx_flag(struct bnx2x_mcast_obj *o) 2460adfc5217SJeff Kirsher { 2461adfc5217SJeff Kirsher struct bnx2x_raw_obj *raw = &o->raw; 2462adfc5217SJeff Kirsher u8 rx_tx_flag = 0; 2463adfc5217SJeff Kirsher 2464adfc5217SJeff Kirsher if ((raw->obj_type == BNX2X_OBJ_TYPE_TX) || 2465adfc5217SJeff Kirsher (raw->obj_type == BNX2X_OBJ_TYPE_RX_TX)) 2466adfc5217SJeff Kirsher rx_tx_flag |= ETH_MULTICAST_RULES_CMD_TX_CMD; 2467adfc5217SJeff Kirsher 2468adfc5217SJeff Kirsher if ((raw->obj_type == BNX2X_OBJ_TYPE_RX) || 2469adfc5217SJeff Kirsher (raw->obj_type == BNX2X_OBJ_TYPE_RX_TX)) 2470adfc5217SJeff Kirsher rx_tx_flag |= ETH_MULTICAST_RULES_CMD_RX_CMD; 2471adfc5217SJeff Kirsher 2472adfc5217SJeff Kirsher return rx_tx_flag; 2473adfc5217SJeff Kirsher } 2474adfc5217SJeff Kirsher 2475adfc5217SJeff Kirsher static void bnx2x_mcast_set_one_rule_e2(struct bnx2x *bp, 2476adfc5217SJeff Kirsher struct bnx2x_mcast_obj *o, int idx, 2477adfc5217SJeff Kirsher union bnx2x_mcast_config_data *cfg_data, 2478adfc5217SJeff Kirsher int cmd) 2479adfc5217SJeff Kirsher { 2480adfc5217SJeff Kirsher struct bnx2x_raw_obj *r = &o->raw; 2481adfc5217SJeff Kirsher struct eth_multicast_rules_ramrod_data *data = 2482adfc5217SJeff Kirsher (struct eth_multicast_rules_ramrod_data *)(r->rdata); 2483adfc5217SJeff Kirsher u8 func_id = r->func_id; 2484adfc5217SJeff Kirsher u8 rx_tx_add_flag = bnx2x_mcast_get_rx_tx_flag(o); 2485adfc5217SJeff Kirsher int bin; 2486adfc5217SJeff Kirsher 2487adfc5217SJeff Kirsher if ((cmd == BNX2X_MCAST_CMD_ADD) || (cmd == BNX2X_MCAST_CMD_RESTORE)) 2488adfc5217SJeff Kirsher rx_tx_add_flag |= ETH_MULTICAST_RULES_CMD_IS_ADD; 2489adfc5217SJeff Kirsher 2490adfc5217SJeff Kirsher data->rules[idx].cmd_general_data |= rx_tx_add_flag; 2491adfc5217SJeff Kirsher 2492adfc5217SJeff Kirsher /* Get a bin and update a bins' vector */ 2493adfc5217SJeff Kirsher switch (cmd) { 2494adfc5217SJeff Kirsher case BNX2X_MCAST_CMD_ADD: 2495adfc5217SJeff Kirsher bin = bnx2x_mcast_bin_from_mac(cfg_data->mac); 2496adfc5217SJeff Kirsher BIT_VEC64_SET_BIT(o->registry.aprox_match.vec, bin); 2497adfc5217SJeff Kirsher break; 2498adfc5217SJeff Kirsher 2499adfc5217SJeff Kirsher case BNX2X_MCAST_CMD_DEL: 2500adfc5217SJeff Kirsher /* If there were no more bins to clear 2501adfc5217SJeff Kirsher * (bnx2x_mcast_clear_first_bin() returns -1) then we would 2502adfc5217SJeff Kirsher * clear any (0xff) bin. 2503adfc5217SJeff Kirsher * See bnx2x_mcast_validate_e2() for explanation when it may 2504adfc5217SJeff Kirsher * happen. 2505adfc5217SJeff Kirsher */ 2506adfc5217SJeff Kirsher bin = bnx2x_mcast_clear_first_bin(o); 2507adfc5217SJeff Kirsher break; 2508adfc5217SJeff Kirsher 2509adfc5217SJeff Kirsher case BNX2X_MCAST_CMD_RESTORE: 2510adfc5217SJeff Kirsher bin = cfg_data->bin; 2511adfc5217SJeff Kirsher break; 2512adfc5217SJeff Kirsher 2513adfc5217SJeff Kirsher default: 2514adfc5217SJeff Kirsher BNX2X_ERR("Unknown command: %d\n", cmd); 2515adfc5217SJeff Kirsher return; 2516adfc5217SJeff Kirsher } 2517adfc5217SJeff Kirsher 2518adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "%s bin %d\n", 2519adfc5217SJeff Kirsher ((rx_tx_add_flag & ETH_MULTICAST_RULES_CMD_IS_ADD) ? 2520adfc5217SJeff Kirsher "Setting" : "Clearing"), bin); 2521adfc5217SJeff Kirsher 2522adfc5217SJeff Kirsher data->rules[idx].bin_id = (u8)bin; 2523adfc5217SJeff Kirsher data->rules[idx].func_id = func_id; 2524adfc5217SJeff Kirsher data->rules[idx].engine_id = o->engine_id; 2525adfc5217SJeff Kirsher } 2526adfc5217SJeff Kirsher 2527adfc5217SJeff Kirsher /** 2528adfc5217SJeff Kirsher * bnx2x_mcast_handle_restore_cmd_e2 - restore configuration from the registry 2529adfc5217SJeff Kirsher * 2530adfc5217SJeff Kirsher * @bp: device handle 2531adfc5217SJeff Kirsher * @o: 2532adfc5217SJeff Kirsher * @start_bin: index in the registry to start from (including) 2533adfc5217SJeff Kirsher * @rdata_idx: index in the ramrod data to start from 2534adfc5217SJeff Kirsher * 2535adfc5217SJeff Kirsher * returns last handled bin index or -1 if all bins have been handled 2536adfc5217SJeff Kirsher */ 2537adfc5217SJeff Kirsher static inline int bnx2x_mcast_handle_restore_cmd_e2( 2538adfc5217SJeff Kirsher struct bnx2x *bp, struct bnx2x_mcast_obj *o , int start_bin, 2539adfc5217SJeff Kirsher int *rdata_idx) 2540adfc5217SJeff Kirsher { 2541adfc5217SJeff Kirsher int cur_bin, cnt = *rdata_idx; 2542adfc5217SJeff Kirsher union bnx2x_mcast_config_data cfg_data = {0}; 2543adfc5217SJeff Kirsher 2544adfc5217SJeff Kirsher /* go through the registry and configure the bins from it */ 2545adfc5217SJeff Kirsher for (cur_bin = bnx2x_mcast_get_next_bin(o, start_bin); cur_bin >= 0; 2546adfc5217SJeff Kirsher cur_bin = bnx2x_mcast_get_next_bin(o, cur_bin + 1)) { 2547adfc5217SJeff Kirsher 2548adfc5217SJeff Kirsher cfg_data.bin = (u8)cur_bin; 2549adfc5217SJeff Kirsher o->set_one_rule(bp, o, cnt, &cfg_data, 2550adfc5217SJeff Kirsher BNX2X_MCAST_CMD_RESTORE); 2551adfc5217SJeff Kirsher 2552adfc5217SJeff Kirsher cnt++; 2553adfc5217SJeff Kirsher 2554adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "About to configure a bin %d\n", cur_bin); 2555adfc5217SJeff Kirsher 2556adfc5217SJeff Kirsher /* Break if we reached the maximum number 2557adfc5217SJeff Kirsher * of rules. 2558adfc5217SJeff Kirsher */ 2559adfc5217SJeff Kirsher if (cnt >= o->max_cmd_len) 2560adfc5217SJeff Kirsher break; 2561adfc5217SJeff Kirsher } 2562adfc5217SJeff Kirsher 2563adfc5217SJeff Kirsher *rdata_idx = cnt; 2564adfc5217SJeff Kirsher 2565adfc5217SJeff Kirsher return cur_bin; 2566adfc5217SJeff Kirsher } 2567adfc5217SJeff Kirsher 2568adfc5217SJeff Kirsher static inline void bnx2x_mcast_hdl_pending_add_e2(struct bnx2x *bp, 2569adfc5217SJeff Kirsher struct bnx2x_mcast_obj *o, struct bnx2x_pending_mcast_cmd *cmd_pos, 2570adfc5217SJeff Kirsher int *line_idx) 2571adfc5217SJeff Kirsher { 2572adfc5217SJeff Kirsher struct bnx2x_mcast_mac_elem *pmac_pos, *pmac_pos_n; 2573adfc5217SJeff Kirsher int cnt = *line_idx; 2574adfc5217SJeff Kirsher union bnx2x_mcast_config_data cfg_data = {0}; 2575adfc5217SJeff Kirsher 2576adfc5217SJeff Kirsher list_for_each_entry_safe(pmac_pos, pmac_pos_n, &cmd_pos->data.macs_head, 2577adfc5217SJeff Kirsher link) { 2578adfc5217SJeff Kirsher 2579adfc5217SJeff Kirsher cfg_data.mac = &pmac_pos->mac[0]; 2580adfc5217SJeff Kirsher o->set_one_rule(bp, o, cnt, &cfg_data, cmd_pos->type); 2581adfc5217SJeff Kirsher 2582adfc5217SJeff Kirsher cnt++; 2583adfc5217SJeff Kirsher 25840f9dad10SJoe Perches DP(BNX2X_MSG_SP, "About to configure %pM mcast MAC\n", 25850f9dad10SJoe Perches pmac_pos->mac); 2586adfc5217SJeff Kirsher 2587adfc5217SJeff Kirsher list_del(&pmac_pos->link); 2588adfc5217SJeff Kirsher 2589adfc5217SJeff Kirsher /* Break if we reached the maximum number 2590adfc5217SJeff Kirsher * of rules. 2591adfc5217SJeff Kirsher */ 2592adfc5217SJeff Kirsher if (cnt >= o->max_cmd_len) 2593adfc5217SJeff Kirsher break; 2594adfc5217SJeff Kirsher } 2595adfc5217SJeff Kirsher 2596adfc5217SJeff Kirsher *line_idx = cnt; 2597adfc5217SJeff Kirsher 2598adfc5217SJeff Kirsher /* if no more MACs to configure - we are done */ 2599adfc5217SJeff Kirsher if (list_empty(&cmd_pos->data.macs_head)) 2600adfc5217SJeff Kirsher cmd_pos->done = true; 2601adfc5217SJeff Kirsher } 2602adfc5217SJeff Kirsher 2603adfc5217SJeff Kirsher static inline void bnx2x_mcast_hdl_pending_del_e2(struct bnx2x *bp, 2604adfc5217SJeff Kirsher struct bnx2x_mcast_obj *o, struct bnx2x_pending_mcast_cmd *cmd_pos, 2605adfc5217SJeff Kirsher int *line_idx) 2606adfc5217SJeff Kirsher { 2607adfc5217SJeff Kirsher int cnt = *line_idx; 2608adfc5217SJeff Kirsher 2609adfc5217SJeff Kirsher while (cmd_pos->data.macs_num) { 2610adfc5217SJeff Kirsher o->set_one_rule(bp, o, cnt, NULL, cmd_pos->type); 2611adfc5217SJeff Kirsher 2612adfc5217SJeff Kirsher cnt++; 2613adfc5217SJeff Kirsher 2614adfc5217SJeff Kirsher cmd_pos->data.macs_num--; 2615adfc5217SJeff Kirsher 2616adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "Deleting MAC. %d left,cnt is %d\n", 2617adfc5217SJeff Kirsher cmd_pos->data.macs_num, cnt); 2618adfc5217SJeff Kirsher 2619adfc5217SJeff Kirsher /* Break if we reached the maximum 2620adfc5217SJeff Kirsher * number of rules. 2621adfc5217SJeff Kirsher */ 2622adfc5217SJeff Kirsher if (cnt >= o->max_cmd_len) 2623adfc5217SJeff Kirsher break; 2624adfc5217SJeff Kirsher } 2625adfc5217SJeff Kirsher 2626adfc5217SJeff Kirsher *line_idx = cnt; 2627adfc5217SJeff Kirsher 2628adfc5217SJeff Kirsher /* If we cleared all bins - we are done */ 2629adfc5217SJeff Kirsher if (!cmd_pos->data.macs_num) 2630adfc5217SJeff Kirsher cmd_pos->done = true; 2631adfc5217SJeff Kirsher } 2632adfc5217SJeff Kirsher 2633adfc5217SJeff Kirsher static inline void bnx2x_mcast_hdl_pending_restore_e2(struct bnx2x *bp, 2634adfc5217SJeff Kirsher struct bnx2x_mcast_obj *o, struct bnx2x_pending_mcast_cmd *cmd_pos, 2635adfc5217SJeff Kirsher int *line_idx) 2636adfc5217SJeff Kirsher { 2637adfc5217SJeff Kirsher cmd_pos->data.next_bin = o->hdl_restore(bp, o, cmd_pos->data.next_bin, 2638adfc5217SJeff Kirsher line_idx); 2639adfc5217SJeff Kirsher 2640adfc5217SJeff Kirsher if (cmd_pos->data.next_bin < 0) 2641adfc5217SJeff Kirsher /* If o->set_restore returned -1 we are done */ 2642adfc5217SJeff Kirsher cmd_pos->done = true; 2643adfc5217SJeff Kirsher else 2644adfc5217SJeff Kirsher /* Start from the next bin next time */ 2645adfc5217SJeff Kirsher cmd_pos->data.next_bin++; 2646adfc5217SJeff Kirsher } 2647adfc5217SJeff Kirsher 2648adfc5217SJeff Kirsher static inline int bnx2x_mcast_handle_pending_cmds_e2(struct bnx2x *bp, 2649adfc5217SJeff Kirsher struct bnx2x_mcast_ramrod_params *p) 2650adfc5217SJeff Kirsher { 2651adfc5217SJeff Kirsher struct bnx2x_pending_mcast_cmd *cmd_pos, *cmd_pos_n; 2652adfc5217SJeff Kirsher int cnt = 0; 2653adfc5217SJeff Kirsher struct bnx2x_mcast_obj *o = p->mcast_obj; 2654adfc5217SJeff Kirsher 2655adfc5217SJeff Kirsher list_for_each_entry_safe(cmd_pos, cmd_pos_n, &o->pending_cmds_head, 2656adfc5217SJeff Kirsher link) { 2657adfc5217SJeff Kirsher switch (cmd_pos->type) { 2658adfc5217SJeff Kirsher case BNX2X_MCAST_CMD_ADD: 2659adfc5217SJeff Kirsher bnx2x_mcast_hdl_pending_add_e2(bp, o, cmd_pos, &cnt); 2660adfc5217SJeff Kirsher break; 2661adfc5217SJeff Kirsher 2662adfc5217SJeff Kirsher case BNX2X_MCAST_CMD_DEL: 2663adfc5217SJeff Kirsher bnx2x_mcast_hdl_pending_del_e2(bp, o, cmd_pos, &cnt); 2664adfc5217SJeff Kirsher break; 2665adfc5217SJeff Kirsher 2666adfc5217SJeff Kirsher case BNX2X_MCAST_CMD_RESTORE: 2667adfc5217SJeff Kirsher bnx2x_mcast_hdl_pending_restore_e2(bp, o, cmd_pos, 2668adfc5217SJeff Kirsher &cnt); 2669adfc5217SJeff Kirsher break; 2670adfc5217SJeff Kirsher 2671adfc5217SJeff Kirsher default: 2672adfc5217SJeff Kirsher BNX2X_ERR("Unknown command: %d\n", cmd_pos->type); 2673adfc5217SJeff Kirsher return -EINVAL; 2674adfc5217SJeff Kirsher } 2675adfc5217SJeff Kirsher 2676adfc5217SJeff Kirsher /* If the command has been completed - remove it from the list 2677adfc5217SJeff Kirsher * and free the memory 2678adfc5217SJeff Kirsher */ 2679adfc5217SJeff Kirsher if (cmd_pos->done) { 2680adfc5217SJeff Kirsher list_del(&cmd_pos->link); 2681adfc5217SJeff Kirsher kfree(cmd_pos); 2682adfc5217SJeff Kirsher } 2683adfc5217SJeff Kirsher 2684adfc5217SJeff Kirsher /* Break if we reached the maximum number of rules */ 2685adfc5217SJeff Kirsher if (cnt >= o->max_cmd_len) 2686adfc5217SJeff Kirsher break; 2687adfc5217SJeff Kirsher } 2688adfc5217SJeff Kirsher 2689adfc5217SJeff Kirsher return cnt; 2690adfc5217SJeff Kirsher } 2691adfc5217SJeff Kirsher 2692adfc5217SJeff Kirsher static inline void bnx2x_mcast_hdl_add(struct bnx2x *bp, 2693adfc5217SJeff Kirsher struct bnx2x_mcast_obj *o, struct bnx2x_mcast_ramrod_params *p, 2694adfc5217SJeff Kirsher int *line_idx) 2695adfc5217SJeff Kirsher { 2696adfc5217SJeff Kirsher struct bnx2x_mcast_list_elem *mlist_pos; 2697adfc5217SJeff Kirsher union bnx2x_mcast_config_data cfg_data = {0}; 2698adfc5217SJeff Kirsher int cnt = *line_idx; 2699adfc5217SJeff Kirsher 2700adfc5217SJeff Kirsher list_for_each_entry(mlist_pos, &p->mcast_list, link) { 2701adfc5217SJeff Kirsher cfg_data.mac = mlist_pos->mac; 2702adfc5217SJeff Kirsher o->set_one_rule(bp, o, cnt, &cfg_data, BNX2X_MCAST_CMD_ADD); 2703adfc5217SJeff Kirsher 2704adfc5217SJeff Kirsher cnt++; 2705adfc5217SJeff Kirsher 27060f9dad10SJoe Perches DP(BNX2X_MSG_SP, "About to configure %pM mcast MAC\n", 27070f9dad10SJoe Perches mlist_pos->mac); 2708adfc5217SJeff Kirsher } 2709adfc5217SJeff Kirsher 2710adfc5217SJeff Kirsher *line_idx = cnt; 2711adfc5217SJeff Kirsher } 2712adfc5217SJeff Kirsher 2713adfc5217SJeff Kirsher static inline void bnx2x_mcast_hdl_del(struct bnx2x *bp, 2714adfc5217SJeff Kirsher struct bnx2x_mcast_obj *o, struct bnx2x_mcast_ramrod_params *p, 2715adfc5217SJeff Kirsher int *line_idx) 2716adfc5217SJeff Kirsher { 2717adfc5217SJeff Kirsher int cnt = *line_idx, i; 2718adfc5217SJeff Kirsher 2719adfc5217SJeff Kirsher for (i = 0; i < p->mcast_list_len; i++) { 2720adfc5217SJeff Kirsher o->set_one_rule(bp, o, cnt, NULL, BNX2X_MCAST_CMD_DEL); 2721adfc5217SJeff Kirsher 2722adfc5217SJeff Kirsher cnt++; 2723adfc5217SJeff Kirsher 2724adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "Deleting MAC. %d left\n", 2725adfc5217SJeff Kirsher p->mcast_list_len - i - 1); 2726adfc5217SJeff Kirsher } 2727adfc5217SJeff Kirsher 2728adfc5217SJeff Kirsher *line_idx = cnt; 2729adfc5217SJeff Kirsher } 2730adfc5217SJeff Kirsher 2731adfc5217SJeff Kirsher /** 2732adfc5217SJeff Kirsher * bnx2x_mcast_handle_current_cmd - 2733adfc5217SJeff Kirsher * 2734adfc5217SJeff Kirsher * @bp: device handle 2735adfc5217SJeff Kirsher * @p: 2736adfc5217SJeff Kirsher * @cmd: 2737adfc5217SJeff Kirsher * @start_cnt: first line in the ramrod data that may be used 2738adfc5217SJeff Kirsher * 2739adfc5217SJeff Kirsher * This function is called iff there is enough place for the current command in 2740adfc5217SJeff Kirsher * the ramrod data. 2741adfc5217SJeff Kirsher * Returns number of lines filled in the ramrod data in total. 2742adfc5217SJeff Kirsher */ 2743adfc5217SJeff Kirsher static inline int bnx2x_mcast_handle_current_cmd(struct bnx2x *bp, 2744adfc5217SJeff Kirsher struct bnx2x_mcast_ramrod_params *p, int cmd, 2745adfc5217SJeff Kirsher int start_cnt) 2746adfc5217SJeff Kirsher { 2747adfc5217SJeff Kirsher struct bnx2x_mcast_obj *o = p->mcast_obj; 2748adfc5217SJeff Kirsher int cnt = start_cnt; 2749adfc5217SJeff Kirsher 2750adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "p->mcast_list_len=%d\n", p->mcast_list_len); 2751adfc5217SJeff Kirsher 2752adfc5217SJeff Kirsher switch (cmd) { 2753adfc5217SJeff Kirsher case BNX2X_MCAST_CMD_ADD: 2754adfc5217SJeff Kirsher bnx2x_mcast_hdl_add(bp, o, p, &cnt); 2755adfc5217SJeff Kirsher break; 2756adfc5217SJeff Kirsher 2757adfc5217SJeff Kirsher case BNX2X_MCAST_CMD_DEL: 2758adfc5217SJeff Kirsher bnx2x_mcast_hdl_del(bp, o, p, &cnt); 2759adfc5217SJeff Kirsher break; 2760adfc5217SJeff Kirsher 2761adfc5217SJeff Kirsher case BNX2X_MCAST_CMD_RESTORE: 2762adfc5217SJeff Kirsher o->hdl_restore(bp, o, 0, &cnt); 2763adfc5217SJeff Kirsher break; 2764adfc5217SJeff Kirsher 2765adfc5217SJeff Kirsher default: 2766adfc5217SJeff Kirsher BNX2X_ERR("Unknown command: %d\n", cmd); 2767adfc5217SJeff Kirsher return -EINVAL; 2768adfc5217SJeff Kirsher } 2769adfc5217SJeff Kirsher 2770adfc5217SJeff Kirsher /* The current command has been handled */ 2771adfc5217SJeff Kirsher p->mcast_list_len = 0; 2772adfc5217SJeff Kirsher 2773adfc5217SJeff Kirsher return cnt; 2774adfc5217SJeff Kirsher } 2775adfc5217SJeff Kirsher 2776adfc5217SJeff Kirsher static int bnx2x_mcast_validate_e2(struct bnx2x *bp, 2777adfc5217SJeff Kirsher struct bnx2x_mcast_ramrod_params *p, 2778adfc5217SJeff Kirsher int cmd) 2779adfc5217SJeff Kirsher { 2780adfc5217SJeff Kirsher struct bnx2x_mcast_obj *o = p->mcast_obj; 2781adfc5217SJeff Kirsher int reg_sz = o->get_registry_size(o); 2782adfc5217SJeff Kirsher 2783adfc5217SJeff Kirsher switch (cmd) { 2784adfc5217SJeff Kirsher /* DEL command deletes all currently configured MACs */ 2785adfc5217SJeff Kirsher case BNX2X_MCAST_CMD_DEL: 2786adfc5217SJeff Kirsher o->set_registry_size(o, 0); 2787adfc5217SJeff Kirsher /* Don't break */ 2788adfc5217SJeff Kirsher 2789adfc5217SJeff Kirsher /* RESTORE command will restore the entire multicast configuration */ 2790adfc5217SJeff Kirsher case BNX2X_MCAST_CMD_RESTORE: 2791adfc5217SJeff Kirsher /* Here we set the approximate amount of work to do, which in 2792adfc5217SJeff Kirsher * fact may be only less as some MACs in postponed ADD 2793adfc5217SJeff Kirsher * command(s) scheduled before this command may fall into 2794adfc5217SJeff Kirsher * the same bin and the actual number of bins set in the 2795adfc5217SJeff Kirsher * registry would be less than we estimated here. See 2796adfc5217SJeff Kirsher * bnx2x_mcast_set_one_rule_e2() for further details. 2797adfc5217SJeff Kirsher */ 2798adfc5217SJeff Kirsher p->mcast_list_len = reg_sz; 2799adfc5217SJeff Kirsher break; 2800adfc5217SJeff Kirsher 2801adfc5217SJeff Kirsher case BNX2X_MCAST_CMD_ADD: 2802adfc5217SJeff Kirsher case BNX2X_MCAST_CMD_CONT: 2803adfc5217SJeff Kirsher /* Here we assume that all new MACs will fall into new bins. 2804adfc5217SJeff Kirsher * However we will correct the real registry size after we 2805adfc5217SJeff Kirsher * handle all pending commands. 2806adfc5217SJeff Kirsher */ 2807adfc5217SJeff Kirsher o->set_registry_size(o, reg_sz + p->mcast_list_len); 2808adfc5217SJeff Kirsher break; 2809adfc5217SJeff Kirsher 2810adfc5217SJeff Kirsher default: 2811adfc5217SJeff Kirsher BNX2X_ERR("Unknown command: %d\n", cmd); 2812adfc5217SJeff Kirsher return -EINVAL; 2813adfc5217SJeff Kirsher 2814adfc5217SJeff Kirsher } 2815adfc5217SJeff Kirsher 2816adfc5217SJeff Kirsher /* Increase the total number of MACs pending to be configured */ 2817adfc5217SJeff Kirsher o->total_pending_num += p->mcast_list_len; 2818adfc5217SJeff Kirsher 2819adfc5217SJeff Kirsher return 0; 2820adfc5217SJeff Kirsher } 2821adfc5217SJeff Kirsher 2822adfc5217SJeff Kirsher static void bnx2x_mcast_revert_e2(struct bnx2x *bp, 2823adfc5217SJeff Kirsher struct bnx2x_mcast_ramrod_params *p, 2824adfc5217SJeff Kirsher int old_num_bins) 2825adfc5217SJeff Kirsher { 2826adfc5217SJeff Kirsher struct bnx2x_mcast_obj *o = p->mcast_obj; 2827adfc5217SJeff Kirsher 2828adfc5217SJeff Kirsher o->set_registry_size(o, old_num_bins); 2829adfc5217SJeff Kirsher o->total_pending_num -= p->mcast_list_len; 2830adfc5217SJeff Kirsher } 2831adfc5217SJeff Kirsher 2832adfc5217SJeff Kirsher /** 2833adfc5217SJeff Kirsher * bnx2x_mcast_set_rdata_hdr_e2 - sets a header values 2834adfc5217SJeff Kirsher * 2835adfc5217SJeff Kirsher * @bp: device handle 2836adfc5217SJeff Kirsher * @p: 2837adfc5217SJeff Kirsher * @len: number of rules to handle 2838adfc5217SJeff Kirsher */ 2839adfc5217SJeff Kirsher static inline void bnx2x_mcast_set_rdata_hdr_e2(struct bnx2x *bp, 2840adfc5217SJeff Kirsher struct bnx2x_mcast_ramrod_params *p, 2841adfc5217SJeff Kirsher u8 len) 2842adfc5217SJeff Kirsher { 2843adfc5217SJeff Kirsher struct bnx2x_raw_obj *r = &p->mcast_obj->raw; 2844adfc5217SJeff Kirsher struct eth_multicast_rules_ramrod_data *data = 2845adfc5217SJeff Kirsher (struct eth_multicast_rules_ramrod_data *)(r->rdata); 2846adfc5217SJeff Kirsher 2847adfc5217SJeff Kirsher data->header.echo = ((r->cid & BNX2X_SWCID_MASK) | 2848adfc5217SJeff Kirsher (BNX2X_FILTER_MCAST_PENDING << BNX2X_SWCID_SHIFT)); 2849adfc5217SJeff Kirsher data->header.rule_cnt = len; 2850adfc5217SJeff Kirsher } 2851adfc5217SJeff Kirsher 2852adfc5217SJeff Kirsher /** 2853adfc5217SJeff Kirsher * bnx2x_mcast_refresh_registry_e2 - recalculate the actual number of set bins 2854adfc5217SJeff Kirsher * 2855adfc5217SJeff Kirsher * @bp: device handle 2856adfc5217SJeff Kirsher * @o: 2857adfc5217SJeff Kirsher * 2858adfc5217SJeff Kirsher * Recalculate the actual number of set bins in the registry using Brian 2859adfc5217SJeff Kirsher * Kernighan's algorithm: it's execution complexity is as a number of set bins. 2860adfc5217SJeff Kirsher * 2861adfc5217SJeff Kirsher * returns 0 for the compliance with bnx2x_mcast_refresh_registry_e1(). 2862adfc5217SJeff Kirsher */ 2863adfc5217SJeff Kirsher static inline int bnx2x_mcast_refresh_registry_e2(struct bnx2x *bp, 2864adfc5217SJeff Kirsher struct bnx2x_mcast_obj *o) 2865adfc5217SJeff Kirsher { 2866adfc5217SJeff Kirsher int i, cnt = 0; 2867adfc5217SJeff Kirsher u64 elem; 2868adfc5217SJeff Kirsher 2869adfc5217SJeff Kirsher for (i = 0; i < BNX2X_MCAST_VEC_SZ; i++) { 2870adfc5217SJeff Kirsher elem = o->registry.aprox_match.vec[i]; 2871adfc5217SJeff Kirsher for (; elem; cnt++) 2872adfc5217SJeff Kirsher elem &= elem - 1; 2873adfc5217SJeff Kirsher } 2874adfc5217SJeff Kirsher 2875adfc5217SJeff Kirsher o->set_registry_size(o, cnt); 2876adfc5217SJeff Kirsher 2877adfc5217SJeff Kirsher return 0; 2878adfc5217SJeff Kirsher } 2879adfc5217SJeff Kirsher 2880adfc5217SJeff Kirsher static int bnx2x_mcast_setup_e2(struct bnx2x *bp, 2881adfc5217SJeff Kirsher struct bnx2x_mcast_ramrod_params *p, 2882adfc5217SJeff Kirsher int cmd) 2883adfc5217SJeff Kirsher { 2884adfc5217SJeff Kirsher struct bnx2x_raw_obj *raw = &p->mcast_obj->raw; 2885adfc5217SJeff Kirsher struct bnx2x_mcast_obj *o = p->mcast_obj; 2886adfc5217SJeff Kirsher struct eth_multicast_rules_ramrod_data *data = 2887adfc5217SJeff Kirsher (struct eth_multicast_rules_ramrod_data *)(raw->rdata); 2888adfc5217SJeff Kirsher int cnt = 0, rc; 2889adfc5217SJeff Kirsher 2890adfc5217SJeff Kirsher /* Reset the ramrod data buffer */ 2891adfc5217SJeff Kirsher memset(data, 0, sizeof(*data)); 2892adfc5217SJeff Kirsher 2893adfc5217SJeff Kirsher cnt = bnx2x_mcast_handle_pending_cmds_e2(bp, p); 2894adfc5217SJeff Kirsher 2895adfc5217SJeff Kirsher /* If there are no more pending commands - clear SCHEDULED state */ 2896adfc5217SJeff Kirsher if (list_empty(&o->pending_cmds_head)) 2897adfc5217SJeff Kirsher o->clear_sched(o); 2898adfc5217SJeff Kirsher 2899adfc5217SJeff Kirsher /* The below may be true iff there was enough room in ramrod 2900adfc5217SJeff Kirsher * data for all pending commands and for the current 2901adfc5217SJeff Kirsher * command. Otherwise the current command would have been added 2902adfc5217SJeff Kirsher * to the pending commands and p->mcast_list_len would have been 2903adfc5217SJeff Kirsher * zeroed. 2904adfc5217SJeff Kirsher */ 2905adfc5217SJeff Kirsher if (p->mcast_list_len > 0) 2906adfc5217SJeff Kirsher cnt = bnx2x_mcast_handle_current_cmd(bp, p, cmd, cnt); 2907adfc5217SJeff Kirsher 2908adfc5217SJeff Kirsher /* We've pulled out some MACs - update the total number of 2909adfc5217SJeff Kirsher * outstanding. 2910adfc5217SJeff Kirsher */ 2911adfc5217SJeff Kirsher o->total_pending_num -= cnt; 2912adfc5217SJeff Kirsher 2913adfc5217SJeff Kirsher /* send a ramrod */ 2914adfc5217SJeff Kirsher WARN_ON(o->total_pending_num < 0); 2915adfc5217SJeff Kirsher WARN_ON(cnt > o->max_cmd_len); 2916adfc5217SJeff Kirsher 2917adfc5217SJeff Kirsher bnx2x_mcast_set_rdata_hdr_e2(bp, p, (u8)cnt); 2918adfc5217SJeff Kirsher 2919adfc5217SJeff Kirsher /* Update a registry size if there are no more pending operations. 2920adfc5217SJeff Kirsher * 2921adfc5217SJeff Kirsher * We don't want to change the value of the registry size if there are 2922adfc5217SJeff Kirsher * pending operations because we want it to always be equal to the 2923adfc5217SJeff Kirsher * exact or the approximate number (see bnx2x_mcast_validate_e2()) of 2924adfc5217SJeff Kirsher * set bins after the last requested operation in order to properly 2925adfc5217SJeff Kirsher * evaluate the size of the next DEL/RESTORE operation. 2926adfc5217SJeff Kirsher * 2927adfc5217SJeff Kirsher * Note that we update the registry itself during command(s) handling 2928adfc5217SJeff Kirsher * - see bnx2x_mcast_set_one_rule_e2(). That's because for 57712 we 2929adfc5217SJeff Kirsher * aggregate multiple commands (ADD/DEL/RESTORE) into one ramrod but 2930adfc5217SJeff Kirsher * with a limited amount of update commands (per MAC/bin) and we don't 2931adfc5217SJeff Kirsher * know in this scope what the actual state of bins configuration is 2932adfc5217SJeff Kirsher * going to be after this ramrod. 2933adfc5217SJeff Kirsher */ 2934adfc5217SJeff Kirsher if (!o->total_pending_num) 2935adfc5217SJeff Kirsher bnx2x_mcast_refresh_registry_e2(bp, o); 2936adfc5217SJeff Kirsher 2937adfc5217SJeff Kirsher /* 2938adfc5217SJeff Kirsher * If CLEAR_ONLY was requested - don't send a ramrod and clear 2939adfc5217SJeff Kirsher * RAMROD_PENDING status immediately. 2940adfc5217SJeff Kirsher */ 2941adfc5217SJeff Kirsher if (test_bit(RAMROD_DRV_CLR_ONLY, &p->ramrod_flags)) { 2942adfc5217SJeff Kirsher raw->clear_pending(raw); 2943adfc5217SJeff Kirsher return 0; 2944adfc5217SJeff Kirsher } else { 2945adfc5217SJeff Kirsher /* 2946adfc5217SJeff Kirsher * No need for an explicit memory barrier here as long we would 2947adfc5217SJeff Kirsher * need to ensure the ordering of writing to the SPQ element 2948adfc5217SJeff Kirsher * and updating of the SPQ producer which involves a memory 2949adfc5217SJeff Kirsher * read and we will have to put a full memory barrier there 2950adfc5217SJeff Kirsher * (inside bnx2x_sp_post()). 2951adfc5217SJeff Kirsher */ 2952adfc5217SJeff Kirsher 2953adfc5217SJeff Kirsher /* Send a ramrod */ 2954adfc5217SJeff Kirsher rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_MULTICAST_RULES, 2955adfc5217SJeff Kirsher raw->cid, U64_HI(raw->rdata_mapping), 2956adfc5217SJeff Kirsher U64_LO(raw->rdata_mapping), 2957adfc5217SJeff Kirsher ETH_CONNECTION_TYPE); 2958adfc5217SJeff Kirsher if (rc) 2959adfc5217SJeff Kirsher return rc; 2960adfc5217SJeff Kirsher 2961adfc5217SJeff Kirsher /* Ramrod completion is pending */ 2962adfc5217SJeff Kirsher return 1; 2963adfc5217SJeff Kirsher } 2964adfc5217SJeff Kirsher } 2965adfc5217SJeff Kirsher 2966adfc5217SJeff Kirsher static int bnx2x_mcast_validate_e1h(struct bnx2x *bp, 2967adfc5217SJeff Kirsher struct bnx2x_mcast_ramrod_params *p, 2968adfc5217SJeff Kirsher int cmd) 2969adfc5217SJeff Kirsher { 2970adfc5217SJeff Kirsher /* Mark, that there is a work to do */ 2971adfc5217SJeff Kirsher if ((cmd == BNX2X_MCAST_CMD_DEL) || (cmd == BNX2X_MCAST_CMD_RESTORE)) 2972adfc5217SJeff Kirsher p->mcast_list_len = 1; 2973adfc5217SJeff Kirsher 2974adfc5217SJeff Kirsher return 0; 2975adfc5217SJeff Kirsher } 2976adfc5217SJeff Kirsher 2977adfc5217SJeff Kirsher static void bnx2x_mcast_revert_e1h(struct bnx2x *bp, 2978adfc5217SJeff Kirsher struct bnx2x_mcast_ramrod_params *p, 2979adfc5217SJeff Kirsher int old_num_bins) 2980adfc5217SJeff Kirsher { 2981adfc5217SJeff Kirsher /* Do nothing */ 2982adfc5217SJeff Kirsher } 2983adfc5217SJeff Kirsher 2984adfc5217SJeff Kirsher #define BNX2X_57711_SET_MC_FILTER(filter, bit) \ 2985adfc5217SJeff Kirsher do { \ 2986adfc5217SJeff Kirsher (filter)[(bit) >> 5] |= (1 << ((bit) & 0x1f)); \ 2987adfc5217SJeff Kirsher } while (0) 2988adfc5217SJeff Kirsher 2989adfc5217SJeff Kirsher static inline void bnx2x_mcast_hdl_add_e1h(struct bnx2x *bp, 2990adfc5217SJeff Kirsher struct bnx2x_mcast_obj *o, 2991adfc5217SJeff Kirsher struct bnx2x_mcast_ramrod_params *p, 2992adfc5217SJeff Kirsher u32 *mc_filter) 2993adfc5217SJeff Kirsher { 2994adfc5217SJeff Kirsher struct bnx2x_mcast_list_elem *mlist_pos; 2995adfc5217SJeff Kirsher int bit; 2996adfc5217SJeff Kirsher 2997adfc5217SJeff Kirsher list_for_each_entry(mlist_pos, &p->mcast_list, link) { 2998adfc5217SJeff Kirsher bit = bnx2x_mcast_bin_from_mac(mlist_pos->mac); 2999adfc5217SJeff Kirsher BNX2X_57711_SET_MC_FILTER(mc_filter, bit); 3000adfc5217SJeff Kirsher 30010f9dad10SJoe Perches DP(BNX2X_MSG_SP, "About to configure %pM mcast MAC, bin %d\n", 30020f9dad10SJoe Perches mlist_pos->mac, bit); 3003adfc5217SJeff Kirsher 3004adfc5217SJeff Kirsher /* bookkeeping... */ 3005adfc5217SJeff Kirsher BIT_VEC64_SET_BIT(o->registry.aprox_match.vec, 3006adfc5217SJeff Kirsher bit); 3007adfc5217SJeff Kirsher } 3008adfc5217SJeff Kirsher } 3009adfc5217SJeff Kirsher 3010adfc5217SJeff Kirsher static inline void bnx2x_mcast_hdl_restore_e1h(struct bnx2x *bp, 3011adfc5217SJeff Kirsher struct bnx2x_mcast_obj *o, struct bnx2x_mcast_ramrod_params *p, 3012adfc5217SJeff Kirsher u32 *mc_filter) 3013adfc5217SJeff Kirsher { 3014adfc5217SJeff Kirsher int bit; 3015adfc5217SJeff Kirsher 3016adfc5217SJeff Kirsher for (bit = bnx2x_mcast_get_next_bin(o, 0); 3017adfc5217SJeff Kirsher bit >= 0; 3018adfc5217SJeff Kirsher bit = bnx2x_mcast_get_next_bin(o, bit + 1)) { 3019adfc5217SJeff Kirsher BNX2X_57711_SET_MC_FILTER(mc_filter, bit); 3020adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "About to set bin %d\n", bit); 3021adfc5217SJeff Kirsher } 3022adfc5217SJeff Kirsher } 3023adfc5217SJeff Kirsher 3024adfc5217SJeff Kirsher /* On 57711 we write the multicast MACs' aproximate match 3025adfc5217SJeff Kirsher * table by directly into the TSTORM's internal RAM. So we don't 3026adfc5217SJeff Kirsher * really need to handle any tricks to make it work. 3027adfc5217SJeff Kirsher */ 3028adfc5217SJeff Kirsher static int bnx2x_mcast_setup_e1h(struct bnx2x *bp, 3029adfc5217SJeff Kirsher struct bnx2x_mcast_ramrod_params *p, 3030adfc5217SJeff Kirsher int cmd) 3031adfc5217SJeff Kirsher { 3032adfc5217SJeff Kirsher int i; 3033adfc5217SJeff Kirsher struct bnx2x_mcast_obj *o = p->mcast_obj; 3034adfc5217SJeff Kirsher struct bnx2x_raw_obj *r = &o->raw; 3035adfc5217SJeff Kirsher 3036adfc5217SJeff Kirsher /* If CLEAR_ONLY has been requested - clear the registry 3037adfc5217SJeff Kirsher * and clear a pending bit. 3038adfc5217SJeff Kirsher */ 3039adfc5217SJeff Kirsher if (!test_bit(RAMROD_DRV_CLR_ONLY, &p->ramrod_flags)) { 3040adfc5217SJeff Kirsher u32 mc_filter[MC_HASH_SIZE] = {0}; 3041adfc5217SJeff Kirsher 3042adfc5217SJeff Kirsher /* Set the multicast filter bits before writing it into 3043adfc5217SJeff Kirsher * the internal memory. 3044adfc5217SJeff Kirsher */ 3045adfc5217SJeff Kirsher switch (cmd) { 3046adfc5217SJeff Kirsher case BNX2X_MCAST_CMD_ADD: 3047adfc5217SJeff Kirsher bnx2x_mcast_hdl_add_e1h(bp, o, p, mc_filter); 3048adfc5217SJeff Kirsher break; 3049adfc5217SJeff Kirsher 3050adfc5217SJeff Kirsher case BNX2X_MCAST_CMD_DEL: 305194f05b0fSJoe Perches DP(BNX2X_MSG_SP, 305294f05b0fSJoe Perches "Invalidating multicast MACs configuration\n"); 3053adfc5217SJeff Kirsher 3054adfc5217SJeff Kirsher /* clear the registry */ 3055adfc5217SJeff Kirsher memset(o->registry.aprox_match.vec, 0, 3056adfc5217SJeff Kirsher sizeof(o->registry.aprox_match.vec)); 3057adfc5217SJeff Kirsher break; 3058adfc5217SJeff Kirsher 3059adfc5217SJeff Kirsher case BNX2X_MCAST_CMD_RESTORE: 3060adfc5217SJeff Kirsher bnx2x_mcast_hdl_restore_e1h(bp, o, p, mc_filter); 3061adfc5217SJeff Kirsher break; 3062adfc5217SJeff Kirsher 3063adfc5217SJeff Kirsher default: 3064adfc5217SJeff Kirsher BNX2X_ERR("Unknown command: %d\n", cmd); 3065adfc5217SJeff Kirsher return -EINVAL; 3066adfc5217SJeff Kirsher } 3067adfc5217SJeff Kirsher 3068adfc5217SJeff Kirsher /* Set the mcast filter in the internal memory */ 3069adfc5217SJeff Kirsher for (i = 0; i < MC_HASH_SIZE; i++) 3070adfc5217SJeff Kirsher REG_WR(bp, MC_HASH_OFFSET(bp, i), mc_filter[i]); 3071adfc5217SJeff Kirsher } else 3072adfc5217SJeff Kirsher /* clear the registry */ 3073adfc5217SJeff Kirsher memset(o->registry.aprox_match.vec, 0, 3074adfc5217SJeff Kirsher sizeof(o->registry.aprox_match.vec)); 3075adfc5217SJeff Kirsher 3076adfc5217SJeff Kirsher /* We are done */ 3077adfc5217SJeff Kirsher r->clear_pending(r); 3078adfc5217SJeff Kirsher 3079adfc5217SJeff Kirsher return 0; 3080adfc5217SJeff Kirsher } 3081adfc5217SJeff Kirsher 3082adfc5217SJeff Kirsher static int bnx2x_mcast_validate_e1(struct bnx2x *bp, 3083adfc5217SJeff Kirsher struct bnx2x_mcast_ramrod_params *p, 3084adfc5217SJeff Kirsher int cmd) 3085adfc5217SJeff Kirsher { 3086adfc5217SJeff Kirsher struct bnx2x_mcast_obj *o = p->mcast_obj; 3087adfc5217SJeff Kirsher int reg_sz = o->get_registry_size(o); 3088adfc5217SJeff Kirsher 3089adfc5217SJeff Kirsher switch (cmd) { 3090adfc5217SJeff Kirsher /* DEL command deletes all currently configured MACs */ 3091adfc5217SJeff Kirsher case BNX2X_MCAST_CMD_DEL: 3092adfc5217SJeff Kirsher o->set_registry_size(o, 0); 3093adfc5217SJeff Kirsher /* Don't break */ 3094adfc5217SJeff Kirsher 3095adfc5217SJeff Kirsher /* RESTORE command will restore the entire multicast configuration */ 3096adfc5217SJeff Kirsher case BNX2X_MCAST_CMD_RESTORE: 3097adfc5217SJeff Kirsher p->mcast_list_len = reg_sz; 3098adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "Command %d, p->mcast_list_len=%d\n", 3099adfc5217SJeff Kirsher cmd, p->mcast_list_len); 3100adfc5217SJeff Kirsher break; 3101adfc5217SJeff Kirsher 3102adfc5217SJeff Kirsher case BNX2X_MCAST_CMD_ADD: 3103adfc5217SJeff Kirsher case BNX2X_MCAST_CMD_CONT: 3104adfc5217SJeff Kirsher /* Multicast MACs on 57710 are configured as unicast MACs and 3105adfc5217SJeff Kirsher * there is only a limited number of CAM entries for that 3106adfc5217SJeff Kirsher * matter. 3107adfc5217SJeff Kirsher */ 3108adfc5217SJeff Kirsher if (p->mcast_list_len > o->max_cmd_len) { 3109adfc5217SJeff Kirsher BNX2X_ERR("Can't configure more than %d multicast MACs" 3110adfc5217SJeff Kirsher "on 57710\n", o->max_cmd_len); 3111adfc5217SJeff Kirsher return -EINVAL; 3112adfc5217SJeff Kirsher } 3113adfc5217SJeff Kirsher /* Every configured MAC should be cleared if DEL command is 3114adfc5217SJeff Kirsher * called. Only the last ADD command is relevant as long as 3115adfc5217SJeff Kirsher * every ADD commands overrides the previous configuration. 3116adfc5217SJeff Kirsher */ 3117adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "p->mcast_list_len=%d\n", p->mcast_list_len); 3118adfc5217SJeff Kirsher if (p->mcast_list_len > 0) 3119adfc5217SJeff Kirsher o->set_registry_size(o, p->mcast_list_len); 3120adfc5217SJeff Kirsher 3121adfc5217SJeff Kirsher break; 3122adfc5217SJeff Kirsher 3123adfc5217SJeff Kirsher default: 3124adfc5217SJeff Kirsher BNX2X_ERR("Unknown command: %d\n", cmd); 3125adfc5217SJeff Kirsher return -EINVAL; 3126adfc5217SJeff Kirsher 3127adfc5217SJeff Kirsher } 3128adfc5217SJeff Kirsher 3129adfc5217SJeff Kirsher /* We want to ensure that commands are executed one by one for 57710. 3130adfc5217SJeff Kirsher * Therefore each none-empty command will consume o->max_cmd_len. 3131adfc5217SJeff Kirsher */ 3132adfc5217SJeff Kirsher if (p->mcast_list_len) 3133adfc5217SJeff Kirsher o->total_pending_num += o->max_cmd_len; 3134adfc5217SJeff Kirsher 3135adfc5217SJeff Kirsher return 0; 3136adfc5217SJeff Kirsher } 3137adfc5217SJeff Kirsher 3138adfc5217SJeff Kirsher static void bnx2x_mcast_revert_e1(struct bnx2x *bp, 3139adfc5217SJeff Kirsher struct bnx2x_mcast_ramrod_params *p, 3140adfc5217SJeff Kirsher int old_num_macs) 3141adfc5217SJeff Kirsher { 3142adfc5217SJeff Kirsher struct bnx2x_mcast_obj *o = p->mcast_obj; 3143adfc5217SJeff Kirsher 3144adfc5217SJeff Kirsher o->set_registry_size(o, old_num_macs); 3145adfc5217SJeff Kirsher 3146adfc5217SJeff Kirsher /* If current command hasn't been handled yet and we are 3147adfc5217SJeff Kirsher * here means that it's meant to be dropped and we have to 3148adfc5217SJeff Kirsher * update the number of outstandling MACs accordingly. 3149adfc5217SJeff Kirsher */ 3150adfc5217SJeff Kirsher if (p->mcast_list_len) 3151adfc5217SJeff Kirsher o->total_pending_num -= o->max_cmd_len; 3152adfc5217SJeff Kirsher } 3153adfc5217SJeff Kirsher 3154adfc5217SJeff Kirsher static void bnx2x_mcast_set_one_rule_e1(struct bnx2x *bp, 3155adfc5217SJeff Kirsher struct bnx2x_mcast_obj *o, int idx, 3156adfc5217SJeff Kirsher union bnx2x_mcast_config_data *cfg_data, 3157adfc5217SJeff Kirsher int cmd) 3158adfc5217SJeff Kirsher { 3159adfc5217SJeff Kirsher struct bnx2x_raw_obj *r = &o->raw; 3160adfc5217SJeff Kirsher struct mac_configuration_cmd *data = 3161adfc5217SJeff Kirsher (struct mac_configuration_cmd *)(r->rdata); 3162adfc5217SJeff Kirsher 3163adfc5217SJeff Kirsher /* copy mac */ 3164adfc5217SJeff Kirsher if ((cmd == BNX2X_MCAST_CMD_ADD) || (cmd == BNX2X_MCAST_CMD_RESTORE)) { 3165adfc5217SJeff Kirsher bnx2x_set_fw_mac_addr(&data->config_table[idx].msb_mac_addr, 3166adfc5217SJeff Kirsher &data->config_table[idx].middle_mac_addr, 3167adfc5217SJeff Kirsher &data->config_table[idx].lsb_mac_addr, 3168adfc5217SJeff Kirsher cfg_data->mac); 3169adfc5217SJeff Kirsher 3170adfc5217SJeff Kirsher data->config_table[idx].vlan_id = 0; 3171adfc5217SJeff Kirsher data->config_table[idx].pf_id = r->func_id; 3172adfc5217SJeff Kirsher data->config_table[idx].clients_bit_vector = 3173adfc5217SJeff Kirsher cpu_to_le32(1 << r->cl_id); 3174adfc5217SJeff Kirsher 3175adfc5217SJeff Kirsher SET_FLAG(data->config_table[idx].flags, 3176adfc5217SJeff Kirsher MAC_CONFIGURATION_ENTRY_ACTION_TYPE, 3177adfc5217SJeff Kirsher T_ETH_MAC_COMMAND_SET); 3178adfc5217SJeff Kirsher } 3179adfc5217SJeff Kirsher } 3180adfc5217SJeff Kirsher 3181adfc5217SJeff Kirsher /** 3182adfc5217SJeff Kirsher * bnx2x_mcast_set_rdata_hdr_e1 - set header values in mac_configuration_cmd 3183adfc5217SJeff Kirsher * 3184adfc5217SJeff Kirsher * @bp: device handle 3185adfc5217SJeff Kirsher * @p: 3186adfc5217SJeff Kirsher * @len: number of rules to handle 3187adfc5217SJeff Kirsher */ 3188adfc5217SJeff Kirsher static inline void bnx2x_mcast_set_rdata_hdr_e1(struct bnx2x *bp, 3189adfc5217SJeff Kirsher struct bnx2x_mcast_ramrod_params *p, 3190adfc5217SJeff Kirsher u8 len) 3191adfc5217SJeff Kirsher { 3192adfc5217SJeff Kirsher struct bnx2x_raw_obj *r = &p->mcast_obj->raw; 3193adfc5217SJeff Kirsher struct mac_configuration_cmd *data = 3194adfc5217SJeff Kirsher (struct mac_configuration_cmd *)(r->rdata); 3195adfc5217SJeff Kirsher 3196adfc5217SJeff Kirsher u8 offset = (CHIP_REV_IS_SLOW(bp) ? 3197adfc5217SJeff Kirsher BNX2X_MAX_EMUL_MULTI*(1 + r->func_id) : 3198adfc5217SJeff Kirsher BNX2X_MAX_MULTICAST*(1 + r->func_id)); 3199adfc5217SJeff Kirsher 3200adfc5217SJeff Kirsher data->hdr.offset = offset; 3201adfc5217SJeff Kirsher data->hdr.client_id = 0xff; 3202adfc5217SJeff Kirsher data->hdr.echo = ((r->cid & BNX2X_SWCID_MASK) | 3203adfc5217SJeff Kirsher (BNX2X_FILTER_MCAST_PENDING << BNX2X_SWCID_SHIFT)); 3204adfc5217SJeff Kirsher data->hdr.length = len; 3205adfc5217SJeff Kirsher } 3206adfc5217SJeff Kirsher 3207adfc5217SJeff Kirsher /** 3208adfc5217SJeff Kirsher * bnx2x_mcast_handle_restore_cmd_e1 - restore command for 57710 3209adfc5217SJeff Kirsher * 3210adfc5217SJeff Kirsher * @bp: device handle 3211adfc5217SJeff Kirsher * @o: 3212adfc5217SJeff Kirsher * @start_idx: index in the registry to start from 3213adfc5217SJeff Kirsher * @rdata_idx: index in the ramrod data to start from 3214adfc5217SJeff Kirsher * 3215adfc5217SJeff Kirsher * restore command for 57710 is like all other commands - always a stand alone 3216adfc5217SJeff Kirsher * command - start_idx and rdata_idx will always be 0. This function will always 3217adfc5217SJeff Kirsher * succeed. 3218adfc5217SJeff Kirsher * returns -1 to comply with 57712 variant. 3219adfc5217SJeff Kirsher */ 3220adfc5217SJeff Kirsher static inline int bnx2x_mcast_handle_restore_cmd_e1( 3221adfc5217SJeff Kirsher struct bnx2x *bp, struct bnx2x_mcast_obj *o , int start_idx, 3222adfc5217SJeff Kirsher int *rdata_idx) 3223adfc5217SJeff Kirsher { 3224adfc5217SJeff Kirsher struct bnx2x_mcast_mac_elem *elem; 3225adfc5217SJeff Kirsher int i = 0; 3226adfc5217SJeff Kirsher union bnx2x_mcast_config_data cfg_data = {0}; 3227adfc5217SJeff Kirsher 3228adfc5217SJeff Kirsher /* go through the registry and configure the MACs from it. */ 3229adfc5217SJeff Kirsher list_for_each_entry(elem, &o->registry.exact_match.macs, link) { 3230adfc5217SJeff Kirsher cfg_data.mac = &elem->mac[0]; 3231adfc5217SJeff Kirsher o->set_one_rule(bp, o, i, &cfg_data, BNX2X_MCAST_CMD_RESTORE); 3232adfc5217SJeff Kirsher 3233adfc5217SJeff Kirsher i++; 3234adfc5217SJeff Kirsher 32350f9dad10SJoe Perches DP(BNX2X_MSG_SP, "About to configure %pM mcast MAC\n", 32360f9dad10SJoe Perches cfg_data.mac); 3237adfc5217SJeff Kirsher } 3238adfc5217SJeff Kirsher 3239adfc5217SJeff Kirsher *rdata_idx = i; 3240adfc5217SJeff Kirsher 3241adfc5217SJeff Kirsher return -1; 3242adfc5217SJeff Kirsher } 3243adfc5217SJeff Kirsher 3244adfc5217SJeff Kirsher 3245adfc5217SJeff Kirsher static inline int bnx2x_mcast_handle_pending_cmds_e1( 3246adfc5217SJeff Kirsher struct bnx2x *bp, struct bnx2x_mcast_ramrod_params *p) 3247adfc5217SJeff Kirsher { 3248adfc5217SJeff Kirsher struct bnx2x_pending_mcast_cmd *cmd_pos; 3249adfc5217SJeff Kirsher struct bnx2x_mcast_mac_elem *pmac_pos; 3250adfc5217SJeff Kirsher struct bnx2x_mcast_obj *o = p->mcast_obj; 3251adfc5217SJeff Kirsher union bnx2x_mcast_config_data cfg_data = {0}; 3252adfc5217SJeff Kirsher int cnt = 0; 3253adfc5217SJeff Kirsher 3254adfc5217SJeff Kirsher 3255adfc5217SJeff Kirsher /* If nothing to be done - return */ 3256adfc5217SJeff Kirsher if (list_empty(&o->pending_cmds_head)) 3257adfc5217SJeff Kirsher return 0; 3258adfc5217SJeff Kirsher 3259adfc5217SJeff Kirsher /* Handle the first command */ 3260adfc5217SJeff Kirsher cmd_pos = list_first_entry(&o->pending_cmds_head, 3261adfc5217SJeff Kirsher struct bnx2x_pending_mcast_cmd, link); 3262adfc5217SJeff Kirsher 3263adfc5217SJeff Kirsher switch (cmd_pos->type) { 3264adfc5217SJeff Kirsher case BNX2X_MCAST_CMD_ADD: 3265adfc5217SJeff Kirsher list_for_each_entry(pmac_pos, &cmd_pos->data.macs_head, link) { 3266adfc5217SJeff Kirsher cfg_data.mac = &pmac_pos->mac[0]; 3267adfc5217SJeff Kirsher o->set_one_rule(bp, o, cnt, &cfg_data, cmd_pos->type); 3268adfc5217SJeff Kirsher 3269adfc5217SJeff Kirsher cnt++; 3270adfc5217SJeff Kirsher 32710f9dad10SJoe Perches DP(BNX2X_MSG_SP, "About to configure %pM mcast MAC\n", 32720f9dad10SJoe Perches pmac_pos->mac); 3273adfc5217SJeff Kirsher } 3274adfc5217SJeff Kirsher break; 3275adfc5217SJeff Kirsher 3276adfc5217SJeff Kirsher case BNX2X_MCAST_CMD_DEL: 3277adfc5217SJeff Kirsher cnt = cmd_pos->data.macs_num; 3278adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "About to delete %d multicast MACs\n", cnt); 3279adfc5217SJeff Kirsher break; 3280adfc5217SJeff Kirsher 3281adfc5217SJeff Kirsher case BNX2X_MCAST_CMD_RESTORE: 3282adfc5217SJeff Kirsher o->hdl_restore(bp, o, 0, &cnt); 3283adfc5217SJeff Kirsher break; 3284adfc5217SJeff Kirsher 3285adfc5217SJeff Kirsher default: 3286adfc5217SJeff Kirsher BNX2X_ERR("Unknown command: %d\n", cmd_pos->type); 3287adfc5217SJeff Kirsher return -EINVAL; 3288adfc5217SJeff Kirsher } 3289adfc5217SJeff Kirsher 3290adfc5217SJeff Kirsher list_del(&cmd_pos->link); 3291adfc5217SJeff Kirsher kfree(cmd_pos); 3292adfc5217SJeff Kirsher 3293adfc5217SJeff Kirsher return cnt; 3294adfc5217SJeff Kirsher } 3295adfc5217SJeff Kirsher 3296adfc5217SJeff Kirsher /** 3297adfc5217SJeff Kirsher * bnx2x_get_fw_mac_addr - revert the bnx2x_set_fw_mac_addr(). 3298adfc5217SJeff Kirsher * 3299adfc5217SJeff Kirsher * @fw_hi: 3300adfc5217SJeff Kirsher * @fw_mid: 3301adfc5217SJeff Kirsher * @fw_lo: 3302adfc5217SJeff Kirsher * @mac: 3303adfc5217SJeff Kirsher */ 3304adfc5217SJeff Kirsher static inline void bnx2x_get_fw_mac_addr(__le16 *fw_hi, __le16 *fw_mid, 3305adfc5217SJeff Kirsher __le16 *fw_lo, u8 *mac) 3306adfc5217SJeff Kirsher { 3307adfc5217SJeff Kirsher mac[1] = ((u8 *)fw_hi)[0]; 3308adfc5217SJeff Kirsher mac[0] = ((u8 *)fw_hi)[1]; 3309adfc5217SJeff Kirsher mac[3] = ((u8 *)fw_mid)[0]; 3310adfc5217SJeff Kirsher mac[2] = ((u8 *)fw_mid)[1]; 3311adfc5217SJeff Kirsher mac[5] = ((u8 *)fw_lo)[0]; 3312adfc5217SJeff Kirsher mac[4] = ((u8 *)fw_lo)[1]; 3313adfc5217SJeff Kirsher } 3314adfc5217SJeff Kirsher 3315adfc5217SJeff Kirsher /** 3316adfc5217SJeff Kirsher * bnx2x_mcast_refresh_registry_e1 - 3317adfc5217SJeff Kirsher * 3318adfc5217SJeff Kirsher * @bp: device handle 3319adfc5217SJeff Kirsher * @cnt: 3320adfc5217SJeff Kirsher * 3321adfc5217SJeff Kirsher * Check the ramrod data first entry flag to see if it's a DELETE or ADD command 3322adfc5217SJeff Kirsher * and update the registry correspondingly: if ADD - allocate a memory and add 3323adfc5217SJeff Kirsher * the entries to the registry (list), if DELETE - clear the registry and free 3324adfc5217SJeff Kirsher * the memory. 3325adfc5217SJeff Kirsher */ 3326adfc5217SJeff Kirsher static inline int bnx2x_mcast_refresh_registry_e1(struct bnx2x *bp, 3327adfc5217SJeff Kirsher struct bnx2x_mcast_obj *o) 3328adfc5217SJeff Kirsher { 3329adfc5217SJeff Kirsher struct bnx2x_raw_obj *raw = &o->raw; 3330adfc5217SJeff Kirsher struct bnx2x_mcast_mac_elem *elem; 3331adfc5217SJeff Kirsher struct mac_configuration_cmd *data = 3332adfc5217SJeff Kirsher (struct mac_configuration_cmd *)(raw->rdata); 3333adfc5217SJeff Kirsher 3334adfc5217SJeff Kirsher /* If first entry contains a SET bit - the command was ADD, 3335adfc5217SJeff Kirsher * otherwise - DEL_ALL 3336adfc5217SJeff Kirsher */ 3337adfc5217SJeff Kirsher if (GET_FLAG(data->config_table[0].flags, 3338adfc5217SJeff Kirsher MAC_CONFIGURATION_ENTRY_ACTION_TYPE)) { 3339adfc5217SJeff Kirsher int i, len = data->hdr.length; 3340adfc5217SJeff Kirsher 3341adfc5217SJeff Kirsher /* Break if it was a RESTORE command */ 3342adfc5217SJeff Kirsher if (!list_empty(&o->registry.exact_match.macs)) 3343adfc5217SJeff Kirsher return 0; 3344adfc5217SJeff Kirsher 3345adfc5217SJeff Kirsher elem = kzalloc(sizeof(*elem)*len, GFP_ATOMIC); 3346adfc5217SJeff Kirsher if (!elem) { 3347adfc5217SJeff Kirsher BNX2X_ERR("Failed to allocate registry memory\n"); 3348adfc5217SJeff Kirsher return -ENOMEM; 3349adfc5217SJeff Kirsher } 3350adfc5217SJeff Kirsher 3351adfc5217SJeff Kirsher for (i = 0; i < len; i++, elem++) { 3352adfc5217SJeff Kirsher bnx2x_get_fw_mac_addr( 3353adfc5217SJeff Kirsher &data->config_table[i].msb_mac_addr, 3354adfc5217SJeff Kirsher &data->config_table[i].middle_mac_addr, 3355adfc5217SJeff Kirsher &data->config_table[i].lsb_mac_addr, 3356adfc5217SJeff Kirsher elem->mac); 33570f9dad10SJoe Perches DP(BNX2X_MSG_SP, "Adding registry entry for [%pM]\n", 33580f9dad10SJoe Perches elem->mac); 3359adfc5217SJeff Kirsher list_add_tail(&elem->link, 3360adfc5217SJeff Kirsher &o->registry.exact_match.macs); 3361adfc5217SJeff Kirsher } 3362adfc5217SJeff Kirsher } else { 3363adfc5217SJeff Kirsher elem = list_first_entry(&o->registry.exact_match.macs, 3364adfc5217SJeff Kirsher struct bnx2x_mcast_mac_elem, link); 3365adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "Deleting a registry\n"); 3366adfc5217SJeff Kirsher kfree(elem); 3367adfc5217SJeff Kirsher INIT_LIST_HEAD(&o->registry.exact_match.macs); 3368adfc5217SJeff Kirsher } 3369adfc5217SJeff Kirsher 3370adfc5217SJeff Kirsher return 0; 3371adfc5217SJeff Kirsher } 3372adfc5217SJeff Kirsher 3373adfc5217SJeff Kirsher static int bnx2x_mcast_setup_e1(struct bnx2x *bp, 3374adfc5217SJeff Kirsher struct bnx2x_mcast_ramrod_params *p, 3375adfc5217SJeff Kirsher int cmd) 3376adfc5217SJeff Kirsher { 3377adfc5217SJeff Kirsher struct bnx2x_mcast_obj *o = p->mcast_obj; 3378adfc5217SJeff Kirsher struct bnx2x_raw_obj *raw = &o->raw; 3379adfc5217SJeff Kirsher struct mac_configuration_cmd *data = 3380adfc5217SJeff Kirsher (struct mac_configuration_cmd *)(raw->rdata); 3381adfc5217SJeff Kirsher int cnt = 0, i, rc; 3382adfc5217SJeff Kirsher 3383adfc5217SJeff Kirsher /* Reset the ramrod data buffer */ 3384adfc5217SJeff Kirsher memset(data, 0, sizeof(*data)); 3385adfc5217SJeff Kirsher 3386adfc5217SJeff Kirsher /* First set all entries as invalid */ 3387adfc5217SJeff Kirsher for (i = 0; i < o->max_cmd_len ; i++) 3388adfc5217SJeff Kirsher SET_FLAG(data->config_table[i].flags, 3389adfc5217SJeff Kirsher MAC_CONFIGURATION_ENTRY_ACTION_TYPE, 3390adfc5217SJeff Kirsher T_ETH_MAC_COMMAND_INVALIDATE); 3391adfc5217SJeff Kirsher 3392adfc5217SJeff Kirsher /* Handle pending commands first */ 3393adfc5217SJeff Kirsher cnt = bnx2x_mcast_handle_pending_cmds_e1(bp, p); 3394adfc5217SJeff Kirsher 3395adfc5217SJeff Kirsher /* If there are no more pending commands - clear SCHEDULED state */ 3396adfc5217SJeff Kirsher if (list_empty(&o->pending_cmds_head)) 3397adfc5217SJeff Kirsher o->clear_sched(o); 3398adfc5217SJeff Kirsher 3399adfc5217SJeff Kirsher /* The below may be true iff there were no pending commands */ 3400adfc5217SJeff Kirsher if (!cnt) 3401adfc5217SJeff Kirsher cnt = bnx2x_mcast_handle_current_cmd(bp, p, cmd, 0); 3402adfc5217SJeff Kirsher 3403adfc5217SJeff Kirsher /* For 57710 every command has o->max_cmd_len length to ensure that 3404adfc5217SJeff Kirsher * commands are done one at a time. 3405adfc5217SJeff Kirsher */ 3406adfc5217SJeff Kirsher o->total_pending_num -= o->max_cmd_len; 3407adfc5217SJeff Kirsher 3408adfc5217SJeff Kirsher /* send a ramrod */ 3409adfc5217SJeff Kirsher 3410adfc5217SJeff Kirsher WARN_ON(cnt > o->max_cmd_len); 3411adfc5217SJeff Kirsher 3412adfc5217SJeff Kirsher /* Set ramrod header (in particular, a number of entries to update) */ 3413adfc5217SJeff Kirsher bnx2x_mcast_set_rdata_hdr_e1(bp, p, (u8)cnt); 3414adfc5217SJeff Kirsher 3415adfc5217SJeff Kirsher /* update a registry: we need the registry contents to be always up 3416adfc5217SJeff Kirsher * to date in order to be able to execute a RESTORE opcode. Here 3417adfc5217SJeff Kirsher * we use the fact that for 57710 we sent one command at a time 3418adfc5217SJeff Kirsher * hence we may take the registry update out of the command handling 3419adfc5217SJeff Kirsher * and do it in a simpler way here. 3420adfc5217SJeff Kirsher */ 3421adfc5217SJeff Kirsher rc = bnx2x_mcast_refresh_registry_e1(bp, o); 3422adfc5217SJeff Kirsher if (rc) 3423adfc5217SJeff Kirsher return rc; 3424adfc5217SJeff Kirsher 3425adfc5217SJeff Kirsher /* 3426adfc5217SJeff Kirsher * If CLEAR_ONLY was requested - don't send a ramrod and clear 3427adfc5217SJeff Kirsher * RAMROD_PENDING status immediately. 3428adfc5217SJeff Kirsher */ 3429adfc5217SJeff Kirsher if (test_bit(RAMROD_DRV_CLR_ONLY, &p->ramrod_flags)) { 3430adfc5217SJeff Kirsher raw->clear_pending(raw); 3431adfc5217SJeff Kirsher return 0; 3432adfc5217SJeff Kirsher } else { 3433adfc5217SJeff Kirsher /* 3434adfc5217SJeff Kirsher * No need for an explicit memory barrier here as long we would 3435adfc5217SJeff Kirsher * need to ensure the ordering of writing to the SPQ element 3436adfc5217SJeff Kirsher * and updating of the SPQ producer which involves a memory 3437adfc5217SJeff Kirsher * read and we will have to put a full memory barrier there 3438adfc5217SJeff Kirsher * (inside bnx2x_sp_post()). 3439adfc5217SJeff Kirsher */ 3440adfc5217SJeff Kirsher 3441adfc5217SJeff Kirsher /* Send a ramrod */ 3442adfc5217SJeff Kirsher rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, raw->cid, 3443adfc5217SJeff Kirsher U64_HI(raw->rdata_mapping), 3444adfc5217SJeff Kirsher U64_LO(raw->rdata_mapping), 3445adfc5217SJeff Kirsher ETH_CONNECTION_TYPE); 3446adfc5217SJeff Kirsher if (rc) 3447adfc5217SJeff Kirsher return rc; 3448adfc5217SJeff Kirsher 3449adfc5217SJeff Kirsher /* Ramrod completion is pending */ 3450adfc5217SJeff Kirsher return 1; 3451adfc5217SJeff Kirsher } 3452adfc5217SJeff Kirsher 3453adfc5217SJeff Kirsher } 3454adfc5217SJeff Kirsher 3455adfc5217SJeff Kirsher static int bnx2x_mcast_get_registry_size_exact(struct bnx2x_mcast_obj *o) 3456adfc5217SJeff Kirsher { 3457adfc5217SJeff Kirsher return o->registry.exact_match.num_macs_set; 3458adfc5217SJeff Kirsher } 3459adfc5217SJeff Kirsher 3460adfc5217SJeff Kirsher static int bnx2x_mcast_get_registry_size_aprox(struct bnx2x_mcast_obj *o) 3461adfc5217SJeff Kirsher { 3462adfc5217SJeff Kirsher return o->registry.aprox_match.num_bins_set; 3463adfc5217SJeff Kirsher } 3464adfc5217SJeff Kirsher 3465adfc5217SJeff Kirsher static void bnx2x_mcast_set_registry_size_exact(struct bnx2x_mcast_obj *o, 3466adfc5217SJeff Kirsher int n) 3467adfc5217SJeff Kirsher { 3468adfc5217SJeff Kirsher o->registry.exact_match.num_macs_set = n; 3469adfc5217SJeff Kirsher } 3470adfc5217SJeff Kirsher 3471adfc5217SJeff Kirsher static void bnx2x_mcast_set_registry_size_aprox(struct bnx2x_mcast_obj *o, 3472adfc5217SJeff Kirsher int n) 3473adfc5217SJeff Kirsher { 3474adfc5217SJeff Kirsher o->registry.aprox_match.num_bins_set = n; 3475adfc5217SJeff Kirsher } 3476adfc5217SJeff Kirsher 3477adfc5217SJeff Kirsher int bnx2x_config_mcast(struct bnx2x *bp, 3478adfc5217SJeff Kirsher struct bnx2x_mcast_ramrod_params *p, 3479adfc5217SJeff Kirsher int cmd) 3480adfc5217SJeff Kirsher { 3481adfc5217SJeff Kirsher struct bnx2x_mcast_obj *o = p->mcast_obj; 3482adfc5217SJeff Kirsher struct bnx2x_raw_obj *r = &o->raw; 3483adfc5217SJeff Kirsher int rc = 0, old_reg_size; 3484adfc5217SJeff Kirsher 3485adfc5217SJeff Kirsher /* This is needed to recover number of currently configured mcast macs 3486adfc5217SJeff Kirsher * in case of failure. 3487adfc5217SJeff Kirsher */ 3488adfc5217SJeff Kirsher old_reg_size = o->get_registry_size(o); 3489adfc5217SJeff Kirsher 3490adfc5217SJeff Kirsher /* Do some calculations and checks */ 3491adfc5217SJeff Kirsher rc = o->validate(bp, p, cmd); 3492adfc5217SJeff Kirsher if (rc) 3493adfc5217SJeff Kirsher return rc; 3494adfc5217SJeff Kirsher 3495adfc5217SJeff Kirsher /* Return if there is no work to do */ 3496adfc5217SJeff Kirsher if ((!p->mcast_list_len) && (!o->check_sched(o))) 3497adfc5217SJeff Kirsher return 0; 3498adfc5217SJeff Kirsher 3499adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "o->total_pending_num=%d p->mcast_list_len=%d " 3500adfc5217SJeff Kirsher "o->max_cmd_len=%d\n", o->total_pending_num, 3501adfc5217SJeff Kirsher p->mcast_list_len, o->max_cmd_len); 3502adfc5217SJeff Kirsher 3503adfc5217SJeff Kirsher /* Enqueue the current command to the pending list if we can't complete 3504adfc5217SJeff Kirsher * it in the current iteration 3505adfc5217SJeff Kirsher */ 3506adfc5217SJeff Kirsher if (r->check_pending(r) || 3507adfc5217SJeff Kirsher ((o->max_cmd_len > 0) && (o->total_pending_num > o->max_cmd_len))) { 3508adfc5217SJeff Kirsher rc = o->enqueue_cmd(bp, p->mcast_obj, p, cmd); 3509adfc5217SJeff Kirsher if (rc < 0) 3510adfc5217SJeff Kirsher goto error_exit1; 3511adfc5217SJeff Kirsher 3512adfc5217SJeff Kirsher /* As long as the current command is in a command list we 3513adfc5217SJeff Kirsher * don't need to handle it separately. 3514adfc5217SJeff Kirsher */ 3515adfc5217SJeff Kirsher p->mcast_list_len = 0; 3516adfc5217SJeff Kirsher } 3517adfc5217SJeff Kirsher 3518adfc5217SJeff Kirsher if (!r->check_pending(r)) { 3519adfc5217SJeff Kirsher 3520adfc5217SJeff Kirsher /* Set 'pending' state */ 3521adfc5217SJeff Kirsher r->set_pending(r); 3522adfc5217SJeff Kirsher 3523adfc5217SJeff Kirsher /* Configure the new classification in the chip */ 3524adfc5217SJeff Kirsher rc = o->config_mcast(bp, p, cmd); 3525adfc5217SJeff Kirsher if (rc < 0) 3526adfc5217SJeff Kirsher goto error_exit2; 3527adfc5217SJeff Kirsher 3528adfc5217SJeff Kirsher /* Wait for a ramrod completion if was requested */ 3529adfc5217SJeff Kirsher if (test_bit(RAMROD_COMP_WAIT, &p->ramrod_flags)) 3530adfc5217SJeff Kirsher rc = o->wait_comp(bp, o); 3531adfc5217SJeff Kirsher } 3532adfc5217SJeff Kirsher 3533adfc5217SJeff Kirsher return rc; 3534adfc5217SJeff Kirsher 3535adfc5217SJeff Kirsher error_exit2: 3536adfc5217SJeff Kirsher r->clear_pending(r); 3537adfc5217SJeff Kirsher 3538adfc5217SJeff Kirsher error_exit1: 3539adfc5217SJeff Kirsher o->revert(bp, p, old_reg_size); 3540adfc5217SJeff Kirsher 3541adfc5217SJeff Kirsher return rc; 3542adfc5217SJeff Kirsher } 3543adfc5217SJeff Kirsher 3544adfc5217SJeff Kirsher static void bnx2x_mcast_clear_sched(struct bnx2x_mcast_obj *o) 3545adfc5217SJeff Kirsher { 3546adfc5217SJeff Kirsher smp_mb__before_clear_bit(); 3547adfc5217SJeff Kirsher clear_bit(o->sched_state, o->raw.pstate); 3548adfc5217SJeff Kirsher smp_mb__after_clear_bit(); 3549adfc5217SJeff Kirsher } 3550adfc5217SJeff Kirsher 3551adfc5217SJeff Kirsher static void bnx2x_mcast_set_sched(struct bnx2x_mcast_obj *o) 3552adfc5217SJeff Kirsher { 3553adfc5217SJeff Kirsher smp_mb__before_clear_bit(); 3554adfc5217SJeff Kirsher set_bit(o->sched_state, o->raw.pstate); 3555adfc5217SJeff Kirsher smp_mb__after_clear_bit(); 3556adfc5217SJeff Kirsher } 3557adfc5217SJeff Kirsher 3558adfc5217SJeff Kirsher static bool bnx2x_mcast_check_sched(struct bnx2x_mcast_obj *o) 3559adfc5217SJeff Kirsher { 3560adfc5217SJeff Kirsher return !!test_bit(o->sched_state, o->raw.pstate); 3561adfc5217SJeff Kirsher } 3562adfc5217SJeff Kirsher 3563adfc5217SJeff Kirsher static bool bnx2x_mcast_check_pending(struct bnx2x_mcast_obj *o) 3564adfc5217SJeff Kirsher { 3565adfc5217SJeff Kirsher return o->raw.check_pending(&o->raw) || o->check_sched(o); 3566adfc5217SJeff Kirsher } 3567adfc5217SJeff Kirsher 3568adfc5217SJeff Kirsher void bnx2x_init_mcast_obj(struct bnx2x *bp, 3569adfc5217SJeff Kirsher struct bnx2x_mcast_obj *mcast_obj, 3570adfc5217SJeff Kirsher u8 mcast_cl_id, u32 mcast_cid, u8 func_id, 3571adfc5217SJeff Kirsher u8 engine_id, void *rdata, dma_addr_t rdata_mapping, 3572adfc5217SJeff Kirsher int state, unsigned long *pstate, bnx2x_obj_type type) 3573adfc5217SJeff Kirsher { 3574adfc5217SJeff Kirsher memset(mcast_obj, 0, sizeof(*mcast_obj)); 3575adfc5217SJeff Kirsher 3576adfc5217SJeff Kirsher bnx2x_init_raw_obj(&mcast_obj->raw, mcast_cl_id, mcast_cid, func_id, 3577adfc5217SJeff Kirsher rdata, rdata_mapping, state, pstate, type); 3578adfc5217SJeff Kirsher 3579adfc5217SJeff Kirsher mcast_obj->engine_id = engine_id; 3580adfc5217SJeff Kirsher 3581adfc5217SJeff Kirsher INIT_LIST_HEAD(&mcast_obj->pending_cmds_head); 3582adfc5217SJeff Kirsher 3583adfc5217SJeff Kirsher mcast_obj->sched_state = BNX2X_FILTER_MCAST_SCHED; 3584adfc5217SJeff Kirsher mcast_obj->check_sched = bnx2x_mcast_check_sched; 3585adfc5217SJeff Kirsher mcast_obj->set_sched = bnx2x_mcast_set_sched; 3586adfc5217SJeff Kirsher mcast_obj->clear_sched = bnx2x_mcast_clear_sched; 3587adfc5217SJeff Kirsher 3588adfc5217SJeff Kirsher if (CHIP_IS_E1(bp)) { 3589adfc5217SJeff Kirsher mcast_obj->config_mcast = bnx2x_mcast_setup_e1; 3590adfc5217SJeff Kirsher mcast_obj->enqueue_cmd = bnx2x_mcast_enqueue_cmd; 3591adfc5217SJeff Kirsher mcast_obj->hdl_restore = 3592adfc5217SJeff Kirsher bnx2x_mcast_handle_restore_cmd_e1; 3593adfc5217SJeff Kirsher mcast_obj->check_pending = bnx2x_mcast_check_pending; 3594adfc5217SJeff Kirsher 3595adfc5217SJeff Kirsher if (CHIP_REV_IS_SLOW(bp)) 3596adfc5217SJeff Kirsher mcast_obj->max_cmd_len = BNX2X_MAX_EMUL_MULTI; 3597adfc5217SJeff Kirsher else 3598adfc5217SJeff Kirsher mcast_obj->max_cmd_len = BNX2X_MAX_MULTICAST; 3599adfc5217SJeff Kirsher 3600adfc5217SJeff Kirsher mcast_obj->wait_comp = bnx2x_mcast_wait; 3601adfc5217SJeff Kirsher mcast_obj->set_one_rule = bnx2x_mcast_set_one_rule_e1; 3602adfc5217SJeff Kirsher mcast_obj->validate = bnx2x_mcast_validate_e1; 3603adfc5217SJeff Kirsher mcast_obj->revert = bnx2x_mcast_revert_e1; 3604adfc5217SJeff Kirsher mcast_obj->get_registry_size = 3605adfc5217SJeff Kirsher bnx2x_mcast_get_registry_size_exact; 3606adfc5217SJeff Kirsher mcast_obj->set_registry_size = 3607adfc5217SJeff Kirsher bnx2x_mcast_set_registry_size_exact; 3608adfc5217SJeff Kirsher 3609adfc5217SJeff Kirsher /* 57710 is the only chip that uses the exact match for mcast 3610adfc5217SJeff Kirsher * at the moment. 3611adfc5217SJeff Kirsher */ 3612adfc5217SJeff Kirsher INIT_LIST_HEAD(&mcast_obj->registry.exact_match.macs); 3613adfc5217SJeff Kirsher 3614adfc5217SJeff Kirsher } else if (CHIP_IS_E1H(bp)) { 3615adfc5217SJeff Kirsher mcast_obj->config_mcast = bnx2x_mcast_setup_e1h; 3616adfc5217SJeff Kirsher mcast_obj->enqueue_cmd = NULL; 3617adfc5217SJeff Kirsher mcast_obj->hdl_restore = NULL; 3618adfc5217SJeff Kirsher mcast_obj->check_pending = bnx2x_mcast_check_pending; 3619adfc5217SJeff Kirsher 3620adfc5217SJeff Kirsher /* 57711 doesn't send a ramrod, so it has unlimited credit 3621adfc5217SJeff Kirsher * for one command. 3622adfc5217SJeff Kirsher */ 3623adfc5217SJeff Kirsher mcast_obj->max_cmd_len = -1; 3624adfc5217SJeff Kirsher mcast_obj->wait_comp = bnx2x_mcast_wait; 3625adfc5217SJeff Kirsher mcast_obj->set_one_rule = NULL; 3626adfc5217SJeff Kirsher mcast_obj->validate = bnx2x_mcast_validate_e1h; 3627adfc5217SJeff Kirsher mcast_obj->revert = bnx2x_mcast_revert_e1h; 3628adfc5217SJeff Kirsher mcast_obj->get_registry_size = 3629adfc5217SJeff Kirsher bnx2x_mcast_get_registry_size_aprox; 3630adfc5217SJeff Kirsher mcast_obj->set_registry_size = 3631adfc5217SJeff Kirsher bnx2x_mcast_set_registry_size_aprox; 3632adfc5217SJeff Kirsher } else { 3633adfc5217SJeff Kirsher mcast_obj->config_mcast = bnx2x_mcast_setup_e2; 3634adfc5217SJeff Kirsher mcast_obj->enqueue_cmd = bnx2x_mcast_enqueue_cmd; 3635adfc5217SJeff Kirsher mcast_obj->hdl_restore = 3636adfc5217SJeff Kirsher bnx2x_mcast_handle_restore_cmd_e2; 3637adfc5217SJeff Kirsher mcast_obj->check_pending = bnx2x_mcast_check_pending; 3638adfc5217SJeff Kirsher /* TODO: There should be a proper HSI define for this number!!! 3639adfc5217SJeff Kirsher */ 3640adfc5217SJeff Kirsher mcast_obj->max_cmd_len = 16; 3641adfc5217SJeff Kirsher mcast_obj->wait_comp = bnx2x_mcast_wait; 3642adfc5217SJeff Kirsher mcast_obj->set_one_rule = bnx2x_mcast_set_one_rule_e2; 3643adfc5217SJeff Kirsher mcast_obj->validate = bnx2x_mcast_validate_e2; 3644adfc5217SJeff Kirsher mcast_obj->revert = bnx2x_mcast_revert_e2; 3645adfc5217SJeff Kirsher mcast_obj->get_registry_size = 3646adfc5217SJeff Kirsher bnx2x_mcast_get_registry_size_aprox; 3647adfc5217SJeff Kirsher mcast_obj->set_registry_size = 3648adfc5217SJeff Kirsher bnx2x_mcast_set_registry_size_aprox; 3649adfc5217SJeff Kirsher } 3650adfc5217SJeff Kirsher } 3651adfc5217SJeff Kirsher 3652adfc5217SJeff Kirsher /*************************** Credit handling **********************************/ 3653adfc5217SJeff Kirsher 3654adfc5217SJeff Kirsher /** 3655adfc5217SJeff Kirsher * atomic_add_ifless - add if the result is less than a given value. 3656adfc5217SJeff Kirsher * 3657adfc5217SJeff Kirsher * @v: pointer of type atomic_t 3658adfc5217SJeff Kirsher * @a: the amount to add to v... 3659adfc5217SJeff Kirsher * @u: ...if (v + a) is less than u. 3660adfc5217SJeff Kirsher * 3661adfc5217SJeff Kirsher * returns true if (v + a) was less than u, and false otherwise. 3662adfc5217SJeff Kirsher * 3663adfc5217SJeff Kirsher */ 3664adfc5217SJeff Kirsher static inline bool __atomic_add_ifless(atomic_t *v, int a, int u) 3665adfc5217SJeff Kirsher { 3666adfc5217SJeff Kirsher int c, old; 3667adfc5217SJeff Kirsher 3668adfc5217SJeff Kirsher c = atomic_read(v); 3669adfc5217SJeff Kirsher for (;;) { 3670adfc5217SJeff Kirsher if (unlikely(c + a >= u)) 3671adfc5217SJeff Kirsher return false; 3672adfc5217SJeff Kirsher 3673adfc5217SJeff Kirsher old = atomic_cmpxchg((v), c, c + a); 3674adfc5217SJeff Kirsher if (likely(old == c)) 3675adfc5217SJeff Kirsher break; 3676adfc5217SJeff Kirsher c = old; 3677adfc5217SJeff Kirsher } 3678adfc5217SJeff Kirsher 3679adfc5217SJeff Kirsher return true; 3680adfc5217SJeff Kirsher } 3681adfc5217SJeff Kirsher 3682adfc5217SJeff Kirsher /** 3683adfc5217SJeff Kirsher * atomic_dec_ifmoe - dec if the result is more or equal than a given value. 3684adfc5217SJeff Kirsher * 3685adfc5217SJeff Kirsher * @v: pointer of type atomic_t 3686adfc5217SJeff Kirsher * @a: the amount to dec from v... 3687adfc5217SJeff Kirsher * @u: ...if (v - a) is more or equal than u. 3688adfc5217SJeff Kirsher * 3689adfc5217SJeff Kirsher * returns true if (v - a) was more or equal than u, and false 3690adfc5217SJeff Kirsher * otherwise. 3691adfc5217SJeff Kirsher */ 3692adfc5217SJeff Kirsher static inline bool __atomic_dec_ifmoe(atomic_t *v, int a, int u) 3693adfc5217SJeff Kirsher { 3694adfc5217SJeff Kirsher int c, old; 3695adfc5217SJeff Kirsher 3696adfc5217SJeff Kirsher c = atomic_read(v); 3697adfc5217SJeff Kirsher for (;;) { 3698adfc5217SJeff Kirsher if (unlikely(c - a < u)) 3699adfc5217SJeff Kirsher return false; 3700adfc5217SJeff Kirsher 3701adfc5217SJeff Kirsher old = atomic_cmpxchg((v), c, c - a); 3702adfc5217SJeff Kirsher if (likely(old == c)) 3703adfc5217SJeff Kirsher break; 3704adfc5217SJeff Kirsher c = old; 3705adfc5217SJeff Kirsher } 3706adfc5217SJeff Kirsher 3707adfc5217SJeff Kirsher return true; 3708adfc5217SJeff Kirsher } 3709adfc5217SJeff Kirsher 3710adfc5217SJeff Kirsher static bool bnx2x_credit_pool_get(struct bnx2x_credit_pool_obj *o, int cnt) 3711adfc5217SJeff Kirsher { 3712adfc5217SJeff Kirsher bool rc; 3713adfc5217SJeff Kirsher 3714adfc5217SJeff Kirsher smp_mb(); 3715adfc5217SJeff Kirsher rc = __atomic_dec_ifmoe(&o->credit, cnt, 0); 3716adfc5217SJeff Kirsher smp_mb(); 3717adfc5217SJeff Kirsher 3718adfc5217SJeff Kirsher return rc; 3719adfc5217SJeff Kirsher } 3720adfc5217SJeff Kirsher 3721adfc5217SJeff Kirsher static bool bnx2x_credit_pool_put(struct bnx2x_credit_pool_obj *o, int cnt) 3722adfc5217SJeff Kirsher { 3723adfc5217SJeff Kirsher bool rc; 3724adfc5217SJeff Kirsher 3725adfc5217SJeff Kirsher smp_mb(); 3726adfc5217SJeff Kirsher 3727adfc5217SJeff Kirsher /* Don't let to refill if credit + cnt > pool_sz */ 3728adfc5217SJeff Kirsher rc = __atomic_add_ifless(&o->credit, cnt, o->pool_sz + 1); 3729adfc5217SJeff Kirsher 3730adfc5217SJeff Kirsher smp_mb(); 3731adfc5217SJeff Kirsher 3732adfc5217SJeff Kirsher return rc; 3733adfc5217SJeff Kirsher } 3734adfc5217SJeff Kirsher 3735adfc5217SJeff Kirsher static int bnx2x_credit_pool_check(struct bnx2x_credit_pool_obj *o) 3736adfc5217SJeff Kirsher { 3737adfc5217SJeff Kirsher int cur_credit; 3738adfc5217SJeff Kirsher 3739adfc5217SJeff Kirsher smp_mb(); 3740adfc5217SJeff Kirsher cur_credit = atomic_read(&o->credit); 3741adfc5217SJeff Kirsher 3742adfc5217SJeff Kirsher return cur_credit; 3743adfc5217SJeff Kirsher } 3744adfc5217SJeff Kirsher 3745adfc5217SJeff Kirsher static bool bnx2x_credit_pool_always_true(struct bnx2x_credit_pool_obj *o, 3746adfc5217SJeff Kirsher int cnt) 3747adfc5217SJeff Kirsher { 3748adfc5217SJeff Kirsher return true; 3749adfc5217SJeff Kirsher } 3750adfc5217SJeff Kirsher 3751adfc5217SJeff Kirsher 3752adfc5217SJeff Kirsher static bool bnx2x_credit_pool_get_entry( 3753adfc5217SJeff Kirsher struct bnx2x_credit_pool_obj *o, 3754adfc5217SJeff Kirsher int *offset) 3755adfc5217SJeff Kirsher { 3756adfc5217SJeff Kirsher int idx, vec, i; 3757adfc5217SJeff Kirsher 3758adfc5217SJeff Kirsher *offset = -1; 3759adfc5217SJeff Kirsher 3760adfc5217SJeff Kirsher /* Find "internal cam-offset" then add to base for this object... */ 3761adfc5217SJeff Kirsher for (vec = 0; vec < BNX2X_POOL_VEC_SIZE; vec++) { 3762adfc5217SJeff Kirsher 3763adfc5217SJeff Kirsher /* Skip the current vector if there are no free entries in it */ 3764adfc5217SJeff Kirsher if (!o->pool_mirror[vec]) 3765adfc5217SJeff Kirsher continue; 3766adfc5217SJeff Kirsher 3767adfc5217SJeff Kirsher /* If we've got here we are going to find a free entry */ 3768adfc5217SJeff Kirsher for (idx = vec * BNX2X_POOL_VEC_SIZE, i = 0; 3769adfc5217SJeff Kirsher i < BIT_VEC64_ELEM_SZ; idx++, i++) 3770adfc5217SJeff Kirsher 3771adfc5217SJeff Kirsher if (BIT_VEC64_TEST_BIT(o->pool_mirror, idx)) { 3772adfc5217SJeff Kirsher /* Got one!! */ 3773adfc5217SJeff Kirsher BIT_VEC64_CLEAR_BIT(o->pool_mirror, idx); 3774adfc5217SJeff Kirsher *offset = o->base_pool_offset + idx; 3775adfc5217SJeff Kirsher return true; 3776adfc5217SJeff Kirsher } 3777adfc5217SJeff Kirsher } 3778adfc5217SJeff Kirsher 3779adfc5217SJeff Kirsher return false; 3780adfc5217SJeff Kirsher } 3781adfc5217SJeff Kirsher 3782adfc5217SJeff Kirsher static bool bnx2x_credit_pool_put_entry( 3783adfc5217SJeff Kirsher struct bnx2x_credit_pool_obj *o, 3784adfc5217SJeff Kirsher int offset) 3785adfc5217SJeff Kirsher { 3786adfc5217SJeff Kirsher if (offset < o->base_pool_offset) 3787adfc5217SJeff Kirsher return false; 3788adfc5217SJeff Kirsher 3789adfc5217SJeff Kirsher offset -= o->base_pool_offset; 3790adfc5217SJeff Kirsher 3791adfc5217SJeff Kirsher if (offset >= o->pool_sz) 3792adfc5217SJeff Kirsher return false; 3793adfc5217SJeff Kirsher 3794adfc5217SJeff Kirsher /* Return the entry to the pool */ 3795adfc5217SJeff Kirsher BIT_VEC64_SET_BIT(o->pool_mirror, offset); 3796adfc5217SJeff Kirsher 3797adfc5217SJeff Kirsher return true; 3798adfc5217SJeff Kirsher } 3799adfc5217SJeff Kirsher 3800adfc5217SJeff Kirsher static bool bnx2x_credit_pool_put_entry_always_true( 3801adfc5217SJeff Kirsher struct bnx2x_credit_pool_obj *o, 3802adfc5217SJeff Kirsher int offset) 3803adfc5217SJeff Kirsher { 3804adfc5217SJeff Kirsher return true; 3805adfc5217SJeff Kirsher } 3806adfc5217SJeff Kirsher 3807adfc5217SJeff Kirsher static bool bnx2x_credit_pool_get_entry_always_true( 3808adfc5217SJeff Kirsher struct bnx2x_credit_pool_obj *o, 3809adfc5217SJeff Kirsher int *offset) 3810adfc5217SJeff Kirsher { 3811adfc5217SJeff Kirsher *offset = -1; 3812adfc5217SJeff Kirsher return true; 3813adfc5217SJeff Kirsher } 3814adfc5217SJeff Kirsher /** 3815adfc5217SJeff Kirsher * bnx2x_init_credit_pool - initialize credit pool internals. 3816adfc5217SJeff Kirsher * 3817adfc5217SJeff Kirsher * @p: 3818adfc5217SJeff Kirsher * @base: Base entry in the CAM to use. 3819adfc5217SJeff Kirsher * @credit: pool size. 3820adfc5217SJeff Kirsher * 3821adfc5217SJeff Kirsher * If base is negative no CAM entries handling will be performed. 3822adfc5217SJeff Kirsher * If credit is negative pool operations will always succeed (unlimited pool). 3823adfc5217SJeff Kirsher * 3824adfc5217SJeff Kirsher */ 3825adfc5217SJeff Kirsher static inline void bnx2x_init_credit_pool(struct bnx2x_credit_pool_obj *p, 3826adfc5217SJeff Kirsher int base, int credit) 3827adfc5217SJeff Kirsher { 3828adfc5217SJeff Kirsher /* Zero the object first */ 3829adfc5217SJeff Kirsher memset(p, 0, sizeof(*p)); 3830adfc5217SJeff Kirsher 3831adfc5217SJeff Kirsher /* Set the table to all 1s */ 3832adfc5217SJeff Kirsher memset(&p->pool_mirror, 0xff, sizeof(p->pool_mirror)); 3833adfc5217SJeff Kirsher 3834adfc5217SJeff Kirsher /* Init a pool as full */ 3835adfc5217SJeff Kirsher atomic_set(&p->credit, credit); 3836adfc5217SJeff Kirsher 3837adfc5217SJeff Kirsher /* The total poll size */ 3838adfc5217SJeff Kirsher p->pool_sz = credit; 3839adfc5217SJeff Kirsher 3840adfc5217SJeff Kirsher p->base_pool_offset = base; 3841adfc5217SJeff Kirsher 3842adfc5217SJeff Kirsher /* Commit the change */ 3843adfc5217SJeff Kirsher smp_mb(); 3844adfc5217SJeff Kirsher 3845adfc5217SJeff Kirsher p->check = bnx2x_credit_pool_check; 3846adfc5217SJeff Kirsher 3847adfc5217SJeff Kirsher /* if pool credit is negative - disable the checks */ 3848adfc5217SJeff Kirsher if (credit >= 0) { 3849adfc5217SJeff Kirsher p->put = bnx2x_credit_pool_put; 3850adfc5217SJeff Kirsher p->get = bnx2x_credit_pool_get; 3851adfc5217SJeff Kirsher p->put_entry = bnx2x_credit_pool_put_entry; 3852adfc5217SJeff Kirsher p->get_entry = bnx2x_credit_pool_get_entry; 3853adfc5217SJeff Kirsher } else { 3854adfc5217SJeff Kirsher p->put = bnx2x_credit_pool_always_true; 3855adfc5217SJeff Kirsher p->get = bnx2x_credit_pool_always_true; 3856adfc5217SJeff Kirsher p->put_entry = bnx2x_credit_pool_put_entry_always_true; 3857adfc5217SJeff Kirsher p->get_entry = bnx2x_credit_pool_get_entry_always_true; 3858adfc5217SJeff Kirsher } 3859adfc5217SJeff Kirsher 3860adfc5217SJeff Kirsher /* If base is negative - disable entries handling */ 3861adfc5217SJeff Kirsher if (base < 0) { 3862adfc5217SJeff Kirsher p->put_entry = bnx2x_credit_pool_put_entry_always_true; 3863adfc5217SJeff Kirsher p->get_entry = bnx2x_credit_pool_get_entry_always_true; 3864adfc5217SJeff Kirsher } 3865adfc5217SJeff Kirsher } 3866adfc5217SJeff Kirsher 3867adfc5217SJeff Kirsher void bnx2x_init_mac_credit_pool(struct bnx2x *bp, 3868adfc5217SJeff Kirsher struct bnx2x_credit_pool_obj *p, u8 func_id, 3869adfc5217SJeff Kirsher u8 func_num) 3870adfc5217SJeff Kirsher { 3871adfc5217SJeff Kirsher /* TODO: this will be defined in consts as well... */ 3872adfc5217SJeff Kirsher #define BNX2X_CAM_SIZE_EMUL 5 3873adfc5217SJeff Kirsher 3874adfc5217SJeff Kirsher int cam_sz; 3875adfc5217SJeff Kirsher 3876adfc5217SJeff Kirsher if (CHIP_IS_E1(bp)) { 3877adfc5217SJeff Kirsher /* In E1, Multicast is saved in cam... */ 3878adfc5217SJeff Kirsher if (!CHIP_REV_IS_SLOW(bp)) 3879adfc5217SJeff Kirsher cam_sz = (MAX_MAC_CREDIT_E1 / 2) - BNX2X_MAX_MULTICAST; 3880adfc5217SJeff Kirsher else 3881adfc5217SJeff Kirsher cam_sz = BNX2X_CAM_SIZE_EMUL - BNX2X_MAX_EMUL_MULTI; 3882adfc5217SJeff Kirsher 3883adfc5217SJeff Kirsher bnx2x_init_credit_pool(p, func_id * cam_sz, cam_sz); 3884adfc5217SJeff Kirsher 3885adfc5217SJeff Kirsher } else if (CHIP_IS_E1H(bp)) { 3886adfc5217SJeff Kirsher /* CAM credit is equaly divided between all active functions 3887adfc5217SJeff Kirsher * on the PORT!. 3888adfc5217SJeff Kirsher */ 3889adfc5217SJeff Kirsher if ((func_num > 0)) { 3890adfc5217SJeff Kirsher if (!CHIP_REV_IS_SLOW(bp)) 3891adfc5217SJeff Kirsher cam_sz = (MAX_MAC_CREDIT_E1H / (2*func_num)); 3892adfc5217SJeff Kirsher else 3893adfc5217SJeff Kirsher cam_sz = BNX2X_CAM_SIZE_EMUL; 3894adfc5217SJeff Kirsher bnx2x_init_credit_pool(p, func_id * cam_sz, cam_sz); 3895adfc5217SJeff Kirsher } else { 3896adfc5217SJeff Kirsher /* this should never happen! Block MAC operations. */ 3897adfc5217SJeff Kirsher bnx2x_init_credit_pool(p, 0, 0); 3898adfc5217SJeff Kirsher } 3899adfc5217SJeff Kirsher 3900adfc5217SJeff Kirsher } else { 3901adfc5217SJeff Kirsher 3902adfc5217SJeff Kirsher /* 3903adfc5217SJeff Kirsher * CAM credit is equaly divided between all active functions 3904adfc5217SJeff Kirsher * on the PATH. 3905adfc5217SJeff Kirsher */ 3906adfc5217SJeff Kirsher if ((func_num > 0)) { 3907adfc5217SJeff Kirsher if (!CHIP_REV_IS_SLOW(bp)) 3908adfc5217SJeff Kirsher cam_sz = (MAX_MAC_CREDIT_E2 / func_num); 3909adfc5217SJeff Kirsher else 3910adfc5217SJeff Kirsher cam_sz = BNX2X_CAM_SIZE_EMUL; 3911adfc5217SJeff Kirsher 3912adfc5217SJeff Kirsher /* 3913adfc5217SJeff Kirsher * No need for CAM entries handling for 57712 and 3914adfc5217SJeff Kirsher * newer. 3915adfc5217SJeff Kirsher */ 3916adfc5217SJeff Kirsher bnx2x_init_credit_pool(p, -1, cam_sz); 3917adfc5217SJeff Kirsher } else { 3918adfc5217SJeff Kirsher /* this should never happen! Block MAC operations. */ 3919adfc5217SJeff Kirsher bnx2x_init_credit_pool(p, 0, 0); 3920adfc5217SJeff Kirsher } 3921adfc5217SJeff Kirsher 3922adfc5217SJeff Kirsher } 3923adfc5217SJeff Kirsher } 3924adfc5217SJeff Kirsher 3925adfc5217SJeff Kirsher void bnx2x_init_vlan_credit_pool(struct bnx2x *bp, 3926adfc5217SJeff Kirsher struct bnx2x_credit_pool_obj *p, 3927adfc5217SJeff Kirsher u8 func_id, 3928adfc5217SJeff Kirsher u8 func_num) 3929adfc5217SJeff Kirsher { 3930adfc5217SJeff Kirsher if (CHIP_IS_E1x(bp)) { 3931adfc5217SJeff Kirsher /* 3932adfc5217SJeff Kirsher * There is no VLAN credit in HW on 57710 and 57711 only 3933adfc5217SJeff Kirsher * MAC / MAC-VLAN can be set 3934adfc5217SJeff Kirsher */ 3935adfc5217SJeff Kirsher bnx2x_init_credit_pool(p, 0, -1); 3936adfc5217SJeff Kirsher } else { 3937adfc5217SJeff Kirsher /* 3938adfc5217SJeff Kirsher * CAM credit is equaly divided between all active functions 3939adfc5217SJeff Kirsher * on the PATH. 3940adfc5217SJeff Kirsher */ 3941adfc5217SJeff Kirsher if (func_num > 0) { 3942adfc5217SJeff Kirsher int credit = MAX_VLAN_CREDIT_E2 / func_num; 3943adfc5217SJeff Kirsher bnx2x_init_credit_pool(p, func_id * credit, credit); 3944adfc5217SJeff Kirsher } else 3945adfc5217SJeff Kirsher /* this should never happen! Block VLAN operations. */ 3946adfc5217SJeff Kirsher bnx2x_init_credit_pool(p, 0, 0); 3947adfc5217SJeff Kirsher } 3948adfc5217SJeff Kirsher } 3949adfc5217SJeff Kirsher 3950adfc5217SJeff Kirsher /****************** RSS Configuration ******************/ 3951adfc5217SJeff Kirsher /** 3952adfc5217SJeff Kirsher * bnx2x_debug_print_ind_table - prints the indirection table configuration. 3953adfc5217SJeff Kirsher * 3954adfc5217SJeff Kirsher * @bp: driver hanlde 3955adfc5217SJeff Kirsher * @p: pointer to rss configuration 3956adfc5217SJeff Kirsher * 3957adfc5217SJeff Kirsher * Prints it when NETIF_MSG_IFUP debug level is configured. 3958adfc5217SJeff Kirsher */ 3959adfc5217SJeff Kirsher static inline void bnx2x_debug_print_ind_table(struct bnx2x *bp, 3960adfc5217SJeff Kirsher struct bnx2x_config_rss_params *p) 3961adfc5217SJeff Kirsher { 3962adfc5217SJeff Kirsher int i; 3963adfc5217SJeff Kirsher 3964adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "Setting indirection table to:\n"); 3965adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "0x0000: "); 3966adfc5217SJeff Kirsher for (i = 0; i < T_ETH_INDIRECTION_TABLE_SIZE; i++) { 3967adfc5217SJeff Kirsher DP_CONT(BNX2X_MSG_SP, "0x%02x ", p->ind_table[i]); 3968adfc5217SJeff Kirsher 3969adfc5217SJeff Kirsher /* Print 4 bytes in a line */ 3970adfc5217SJeff Kirsher if ((i + 1 < T_ETH_INDIRECTION_TABLE_SIZE) && 3971adfc5217SJeff Kirsher (((i + 1) & 0x3) == 0)) { 3972adfc5217SJeff Kirsher DP_CONT(BNX2X_MSG_SP, "\n"); 3973adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "0x%04x: ", i + 1); 3974adfc5217SJeff Kirsher } 3975adfc5217SJeff Kirsher } 3976adfc5217SJeff Kirsher 3977adfc5217SJeff Kirsher DP_CONT(BNX2X_MSG_SP, "\n"); 3978adfc5217SJeff Kirsher } 3979adfc5217SJeff Kirsher 3980adfc5217SJeff Kirsher /** 3981adfc5217SJeff Kirsher * bnx2x_setup_rss - configure RSS 3982adfc5217SJeff Kirsher * 3983adfc5217SJeff Kirsher * @bp: device handle 3984adfc5217SJeff Kirsher * @p: rss configuration 3985adfc5217SJeff Kirsher * 3986adfc5217SJeff Kirsher * sends on UPDATE ramrod for that matter. 3987adfc5217SJeff Kirsher */ 3988adfc5217SJeff Kirsher static int bnx2x_setup_rss(struct bnx2x *bp, 3989adfc5217SJeff Kirsher struct bnx2x_config_rss_params *p) 3990adfc5217SJeff Kirsher { 3991adfc5217SJeff Kirsher struct bnx2x_rss_config_obj *o = p->rss_obj; 3992adfc5217SJeff Kirsher struct bnx2x_raw_obj *r = &o->raw; 3993adfc5217SJeff Kirsher struct eth_rss_update_ramrod_data *data = 3994adfc5217SJeff Kirsher (struct eth_rss_update_ramrod_data *)(r->rdata); 3995adfc5217SJeff Kirsher u8 rss_mode = 0; 3996adfc5217SJeff Kirsher int rc; 3997adfc5217SJeff Kirsher 3998adfc5217SJeff Kirsher memset(data, 0, sizeof(*data)); 3999adfc5217SJeff Kirsher 4000adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "Configuring RSS\n"); 4001adfc5217SJeff Kirsher 4002adfc5217SJeff Kirsher /* Set an echo field */ 4003adfc5217SJeff Kirsher data->echo = (r->cid & BNX2X_SWCID_MASK) | 4004adfc5217SJeff Kirsher (r->state << BNX2X_SWCID_SHIFT); 4005adfc5217SJeff Kirsher 4006adfc5217SJeff Kirsher /* RSS mode */ 4007adfc5217SJeff Kirsher if (test_bit(BNX2X_RSS_MODE_DISABLED, &p->rss_flags)) 4008adfc5217SJeff Kirsher rss_mode = ETH_RSS_MODE_DISABLED; 4009adfc5217SJeff Kirsher else if (test_bit(BNX2X_RSS_MODE_REGULAR, &p->rss_flags)) 4010adfc5217SJeff Kirsher rss_mode = ETH_RSS_MODE_REGULAR; 4011adfc5217SJeff Kirsher else if (test_bit(BNX2X_RSS_MODE_VLAN_PRI, &p->rss_flags)) 4012adfc5217SJeff Kirsher rss_mode = ETH_RSS_MODE_VLAN_PRI; 4013adfc5217SJeff Kirsher else if (test_bit(BNX2X_RSS_MODE_E1HOV_PRI, &p->rss_flags)) 4014adfc5217SJeff Kirsher rss_mode = ETH_RSS_MODE_E1HOV_PRI; 4015adfc5217SJeff Kirsher else if (test_bit(BNX2X_RSS_MODE_IP_DSCP, &p->rss_flags)) 4016adfc5217SJeff Kirsher rss_mode = ETH_RSS_MODE_IP_DSCP; 4017adfc5217SJeff Kirsher 4018adfc5217SJeff Kirsher data->rss_mode = rss_mode; 4019adfc5217SJeff Kirsher 4020adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "rss_mode=%d\n", rss_mode); 4021adfc5217SJeff Kirsher 4022adfc5217SJeff Kirsher /* RSS capabilities */ 4023adfc5217SJeff Kirsher if (test_bit(BNX2X_RSS_IPV4, &p->rss_flags)) 4024adfc5217SJeff Kirsher data->capabilities |= 4025adfc5217SJeff Kirsher ETH_RSS_UPDATE_RAMROD_DATA_IPV4_CAPABILITY; 4026adfc5217SJeff Kirsher 4027adfc5217SJeff Kirsher if (test_bit(BNX2X_RSS_IPV4_TCP, &p->rss_flags)) 4028adfc5217SJeff Kirsher data->capabilities |= 4029adfc5217SJeff Kirsher ETH_RSS_UPDATE_RAMROD_DATA_IPV4_TCP_CAPABILITY; 4030adfc5217SJeff Kirsher 4031adfc5217SJeff Kirsher if (test_bit(BNX2X_RSS_IPV6, &p->rss_flags)) 4032adfc5217SJeff Kirsher data->capabilities |= 4033adfc5217SJeff Kirsher ETH_RSS_UPDATE_RAMROD_DATA_IPV6_CAPABILITY; 4034adfc5217SJeff Kirsher 4035adfc5217SJeff Kirsher if (test_bit(BNX2X_RSS_IPV6_TCP, &p->rss_flags)) 4036adfc5217SJeff Kirsher data->capabilities |= 4037adfc5217SJeff Kirsher ETH_RSS_UPDATE_RAMROD_DATA_IPV6_TCP_CAPABILITY; 4038adfc5217SJeff Kirsher 4039adfc5217SJeff Kirsher /* Hashing mask */ 4040adfc5217SJeff Kirsher data->rss_result_mask = p->rss_result_mask; 4041adfc5217SJeff Kirsher 4042adfc5217SJeff Kirsher /* RSS engine ID */ 4043adfc5217SJeff Kirsher data->rss_engine_id = o->engine_id; 4044adfc5217SJeff Kirsher 4045adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "rss_engine_id=%d\n", data->rss_engine_id); 4046adfc5217SJeff Kirsher 4047adfc5217SJeff Kirsher /* Indirection table */ 4048adfc5217SJeff Kirsher memcpy(data->indirection_table, p->ind_table, 4049adfc5217SJeff Kirsher T_ETH_INDIRECTION_TABLE_SIZE); 4050adfc5217SJeff Kirsher 4051adfc5217SJeff Kirsher /* Remember the last configuration */ 4052adfc5217SJeff Kirsher memcpy(o->ind_table, p->ind_table, T_ETH_INDIRECTION_TABLE_SIZE); 4053adfc5217SJeff Kirsher 4054adfc5217SJeff Kirsher /* Print the indirection table */ 4055adfc5217SJeff Kirsher if (netif_msg_ifup(bp)) 4056adfc5217SJeff Kirsher bnx2x_debug_print_ind_table(bp, p); 4057adfc5217SJeff Kirsher 4058adfc5217SJeff Kirsher /* RSS keys */ 4059adfc5217SJeff Kirsher if (test_bit(BNX2X_RSS_SET_SRCH, &p->rss_flags)) { 4060adfc5217SJeff Kirsher memcpy(&data->rss_key[0], &p->rss_key[0], 4061adfc5217SJeff Kirsher sizeof(data->rss_key)); 4062adfc5217SJeff Kirsher data->capabilities |= ETH_RSS_UPDATE_RAMROD_DATA_UPDATE_RSS_KEY; 4063adfc5217SJeff Kirsher } 4064adfc5217SJeff Kirsher 4065adfc5217SJeff Kirsher /* 4066adfc5217SJeff Kirsher * No need for an explicit memory barrier here as long we would 4067adfc5217SJeff Kirsher * need to ensure the ordering of writing to the SPQ element 4068adfc5217SJeff Kirsher * and updating of the SPQ producer which involves a memory 4069adfc5217SJeff Kirsher * read and we will have to put a full memory barrier there 4070adfc5217SJeff Kirsher * (inside bnx2x_sp_post()). 4071adfc5217SJeff Kirsher */ 4072adfc5217SJeff Kirsher 4073adfc5217SJeff Kirsher /* Send a ramrod */ 4074adfc5217SJeff Kirsher rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_RSS_UPDATE, r->cid, 4075adfc5217SJeff Kirsher U64_HI(r->rdata_mapping), 4076adfc5217SJeff Kirsher U64_LO(r->rdata_mapping), 4077adfc5217SJeff Kirsher ETH_CONNECTION_TYPE); 4078adfc5217SJeff Kirsher 4079adfc5217SJeff Kirsher if (rc < 0) 4080adfc5217SJeff Kirsher return rc; 4081adfc5217SJeff Kirsher 4082adfc5217SJeff Kirsher return 1; 4083adfc5217SJeff Kirsher } 4084adfc5217SJeff Kirsher 4085adfc5217SJeff Kirsher void bnx2x_get_rss_ind_table(struct bnx2x_rss_config_obj *rss_obj, 4086adfc5217SJeff Kirsher u8 *ind_table) 4087adfc5217SJeff Kirsher { 4088adfc5217SJeff Kirsher memcpy(ind_table, rss_obj->ind_table, sizeof(rss_obj->ind_table)); 4089adfc5217SJeff Kirsher } 4090adfc5217SJeff Kirsher 4091adfc5217SJeff Kirsher int bnx2x_config_rss(struct bnx2x *bp, 4092adfc5217SJeff Kirsher struct bnx2x_config_rss_params *p) 4093adfc5217SJeff Kirsher { 4094adfc5217SJeff Kirsher int rc; 4095adfc5217SJeff Kirsher struct bnx2x_rss_config_obj *o = p->rss_obj; 4096adfc5217SJeff Kirsher struct bnx2x_raw_obj *r = &o->raw; 4097adfc5217SJeff Kirsher 4098adfc5217SJeff Kirsher /* Do nothing if only driver cleanup was requested */ 4099adfc5217SJeff Kirsher if (test_bit(RAMROD_DRV_CLR_ONLY, &p->ramrod_flags)) 4100adfc5217SJeff Kirsher return 0; 4101adfc5217SJeff Kirsher 4102adfc5217SJeff Kirsher r->set_pending(r); 4103adfc5217SJeff Kirsher 4104adfc5217SJeff Kirsher rc = o->config_rss(bp, p); 4105adfc5217SJeff Kirsher if (rc < 0) { 4106adfc5217SJeff Kirsher r->clear_pending(r); 4107adfc5217SJeff Kirsher return rc; 4108adfc5217SJeff Kirsher } 4109adfc5217SJeff Kirsher 4110adfc5217SJeff Kirsher if (test_bit(RAMROD_COMP_WAIT, &p->ramrod_flags)) 4111adfc5217SJeff Kirsher rc = r->wait_comp(bp, r); 4112adfc5217SJeff Kirsher 4113adfc5217SJeff Kirsher return rc; 4114adfc5217SJeff Kirsher } 4115adfc5217SJeff Kirsher 4116adfc5217SJeff Kirsher 4117adfc5217SJeff Kirsher void bnx2x_init_rss_config_obj(struct bnx2x *bp, 4118adfc5217SJeff Kirsher struct bnx2x_rss_config_obj *rss_obj, 4119adfc5217SJeff Kirsher u8 cl_id, u32 cid, u8 func_id, u8 engine_id, 4120adfc5217SJeff Kirsher void *rdata, dma_addr_t rdata_mapping, 4121adfc5217SJeff Kirsher int state, unsigned long *pstate, 4122adfc5217SJeff Kirsher bnx2x_obj_type type) 4123adfc5217SJeff Kirsher { 4124adfc5217SJeff Kirsher bnx2x_init_raw_obj(&rss_obj->raw, cl_id, cid, func_id, rdata, 4125adfc5217SJeff Kirsher rdata_mapping, state, pstate, type); 4126adfc5217SJeff Kirsher 4127adfc5217SJeff Kirsher rss_obj->engine_id = engine_id; 4128adfc5217SJeff Kirsher rss_obj->config_rss = bnx2x_setup_rss; 4129adfc5217SJeff Kirsher } 4130adfc5217SJeff Kirsher 4131adfc5217SJeff Kirsher /********************** Queue state object ***********************************/ 4132adfc5217SJeff Kirsher 4133adfc5217SJeff Kirsher /** 4134adfc5217SJeff Kirsher * bnx2x_queue_state_change - perform Queue state change transition 4135adfc5217SJeff Kirsher * 4136adfc5217SJeff Kirsher * @bp: device handle 4137adfc5217SJeff Kirsher * @params: parameters to perform the transition 4138adfc5217SJeff Kirsher * 4139adfc5217SJeff Kirsher * returns 0 in case of successfully completed transition, negative error 4140adfc5217SJeff Kirsher * code in case of failure, positive (EBUSY) value if there is a completion 4141adfc5217SJeff Kirsher * to that is still pending (possible only if RAMROD_COMP_WAIT is 4142adfc5217SJeff Kirsher * not set in params->ramrod_flags for asynchronous commands). 4143adfc5217SJeff Kirsher * 4144adfc5217SJeff Kirsher */ 4145adfc5217SJeff Kirsher int bnx2x_queue_state_change(struct bnx2x *bp, 4146adfc5217SJeff Kirsher struct bnx2x_queue_state_params *params) 4147adfc5217SJeff Kirsher { 4148adfc5217SJeff Kirsher struct bnx2x_queue_sp_obj *o = params->q_obj; 4149adfc5217SJeff Kirsher int rc, pending_bit; 4150adfc5217SJeff Kirsher unsigned long *pending = &o->pending; 4151adfc5217SJeff Kirsher 4152adfc5217SJeff Kirsher /* Check that the requested transition is legal */ 4153adfc5217SJeff Kirsher if (o->check_transition(bp, o, params)) 4154adfc5217SJeff Kirsher return -EINVAL; 4155adfc5217SJeff Kirsher 4156adfc5217SJeff Kirsher /* Set "pending" bit */ 4157adfc5217SJeff Kirsher pending_bit = o->set_pending(o, params); 4158adfc5217SJeff Kirsher 4159adfc5217SJeff Kirsher /* Don't send a command if only driver cleanup was requested */ 4160adfc5217SJeff Kirsher if (test_bit(RAMROD_DRV_CLR_ONLY, ¶ms->ramrod_flags)) 4161adfc5217SJeff Kirsher o->complete_cmd(bp, o, pending_bit); 4162adfc5217SJeff Kirsher else { 4163adfc5217SJeff Kirsher /* Send a ramrod */ 4164adfc5217SJeff Kirsher rc = o->send_cmd(bp, params); 4165adfc5217SJeff Kirsher if (rc) { 4166adfc5217SJeff Kirsher o->next_state = BNX2X_Q_STATE_MAX; 4167adfc5217SJeff Kirsher clear_bit(pending_bit, pending); 4168adfc5217SJeff Kirsher smp_mb__after_clear_bit(); 4169adfc5217SJeff Kirsher return rc; 4170adfc5217SJeff Kirsher } 4171adfc5217SJeff Kirsher 4172adfc5217SJeff Kirsher if (test_bit(RAMROD_COMP_WAIT, ¶ms->ramrod_flags)) { 4173adfc5217SJeff Kirsher rc = o->wait_comp(bp, o, pending_bit); 4174adfc5217SJeff Kirsher if (rc) 4175adfc5217SJeff Kirsher return rc; 4176adfc5217SJeff Kirsher 4177adfc5217SJeff Kirsher return 0; 4178adfc5217SJeff Kirsher } 4179adfc5217SJeff Kirsher } 4180adfc5217SJeff Kirsher 4181adfc5217SJeff Kirsher return !!test_bit(pending_bit, pending); 4182adfc5217SJeff Kirsher } 4183adfc5217SJeff Kirsher 4184adfc5217SJeff Kirsher 4185adfc5217SJeff Kirsher static int bnx2x_queue_set_pending(struct bnx2x_queue_sp_obj *obj, 4186adfc5217SJeff Kirsher struct bnx2x_queue_state_params *params) 4187adfc5217SJeff Kirsher { 4188adfc5217SJeff Kirsher enum bnx2x_queue_cmd cmd = params->cmd, bit; 4189adfc5217SJeff Kirsher 4190adfc5217SJeff Kirsher /* ACTIVATE and DEACTIVATE commands are implemented on top of 4191adfc5217SJeff Kirsher * UPDATE command. 4192adfc5217SJeff Kirsher */ 4193adfc5217SJeff Kirsher if ((cmd == BNX2X_Q_CMD_ACTIVATE) || 4194adfc5217SJeff Kirsher (cmd == BNX2X_Q_CMD_DEACTIVATE)) 4195adfc5217SJeff Kirsher bit = BNX2X_Q_CMD_UPDATE; 4196adfc5217SJeff Kirsher else 4197adfc5217SJeff Kirsher bit = cmd; 4198adfc5217SJeff Kirsher 4199adfc5217SJeff Kirsher set_bit(bit, &obj->pending); 4200adfc5217SJeff Kirsher return bit; 4201adfc5217SJeff Kirsher } 4202adfc5217SJeff Kirsher 4203adfc5217SJeff Kirsher static int bnx2x_queue_wait_comp(struct bnx2x *bp, 4204adfc5217SJeff Kirsher struct bnx2x_queue_sp_obj *o, 4205adfc5217SJeff Kirsher enum bnx2x_queue_cmd cmd) 4206adfc5217SJeff Kirsher { 4207adfc5217SJeff Kirsher return bnx2x_state_wait(bp, cmd, &o->pending); 4208adfc5217SJeff Kirsher } 4209adfc5217SJeff Kirsher 4210adfc5217SJeff Kirsher /** 4211adfc5217SJeff Kirsher * bnx2x_queue_comp_cmd - complete the state change command. 4212adfc5217SJeff Kirsher * 4213adfc5217SJeff Kirsher * @bp: device handle 4214adfc5217SJeff Kirsher * @o: 4215adfc5217SJeff Kirsher * @cmd: 4216adfc5217SJeff Kirsher * 4217adfc5217SJeff Kirsher * Checks that the arrived completion is expected. 4218adfc5217SJeff Kirsher */ 4219adfc5217SJeff Kirsher static int bnx2x_queue_comp_cmd(struct bnx2x *bp, 4220adfc5217SJeff Kirsher struct bnx2x_queue_sp_obj *o, 4221adfc5217SJeff Kirsher enum bnx2x_queue_cmd cmd) 4222adfc5217SJeff Kirsher { 4223adfc5217SJeff Kirsher unsigned long cur_pending = o->pending; 4224adfc5217SJeff Kirsher 4225adfc5217SJeff Kirsher if (!test_and_clear_bit(cmd, &cur_pending)) { 4226adfc5217SJeff Kirsher BNX2X_ERR("Bad MC reply %d for queue %d in state %d " 4227adfc5217SJeff Kirsher "pending 0x%lx, next_state %d\n", cmd, 4228adfc5217SJeff Kirsher o->cids[BNX2X_PRIMARY_CID_INDEX], 4229adfc5217SJeff Kirsher o->state, cur_pending, o->next_state); 4230adfc5217SJeff Kirsher return -EINVAL; 4231adfc5217SJeff Kirsher } 4232adfc5217SJeff Kirsher 4233adfc5217SJeff Kirsher if (o->next_tx_only >= o->max_cos) 4234adfc5217SJeff Kirsher /* >= becuase tx only must always be smaller than cos since the 4235adfc5217SJeff Kirsher * primary connection suports COS 0 4236adfc5217SJeff Kirsher */ 4237adfc5217SJeff Kirsher BNX2X_ERR("illegal value for next tx_only: %d. max cos was %d", 4238adfc5217SJeff Kirsher o->next_tx_only, o->max_cos); 4239adfc5217SJeff Kirsher 4240adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "Completing command %d for queue %d, " 4241adfc5217SJeff Kirsher "setting state to %d\n", cmd, 4242adfc5217SJeff Kirsher o->cids[BNX2X_PRIMARY_CID_INDEX], o->next_state); 4243adfc5217SJeff Kirsher 4244adfc5217SJeff Kirsher if (o->next_tx_only) /* print num tx-only if any exist */ 424594f05b0fSJoe Perches DP(BNX2X_MSG_SP, "primary cid %d: num tx-only cons %d\n", 4246adfc5217SJeff Kirsher o->cids[BNX2X_PRIMARY_CID_INDEX], o->next_tx_only); 4247adfc5217SJeff Kirsher 4248adfc5217SJeff Kirsher o->state = o->next_state; 4249adfc5217SJeff Kirsher o->num_tx_only = o->next_tx_only; 4250adfc5217SJeff Kirsher o->next_state = BNX2X_Q_STATE_MAX; 4251adfc5217SJeff Kirsher 4252adfc5217SJeff Kirsher /* It's important that o->state and o->next_state are 4253adfc5217SJeff Kirsher * updated before o->pending. 4254adfc5217SJeff Kirsher */ 4255adfc5217SJeff Kirsher wmb(); 4256adfc5217SJeff Kirsher 4257adfc5217SJeff Kirsher clear_bit(cmd, &o->pending); 4258adfc5217SJeff Kirsher smp_mb__after_clear_bit(); 4259adfc5217SJeff Kirsher 4260adfc5217SJeff Kirsher return 0; 4261adfc5217SJeff Kirsher } 4262adfc5217SJeff Kirsher 4263adfc5217SJeff Kirsher static void bnx2x_q_fill_setup_data_e2(struct bnx2x *bp, 4264adfc5217SJeff Kirsher struct bnx2x_queue_state_params *cmd_params, 4265adfc5217SJeff Kirsher struct client_init_ramrod_data *data) 4266adfc5217SJeff Kirsher { 4267adfc5217SJeff Kirsher struct bnx2x_queue_setup_params *params = &cmd_params->params.setup; 4268adfc5217SJeff Kirsher 4269adfc5217SJeff Kirsher /* Rx data */ 4270adfc5217SJeff Kirsher 4271adfc5217SJeff Kirsher /* IPv6 TPA supported for E2 and above only */ 4272adfc5217SJeff Kirsher data->rx.tpa_en |= test_bit(BNX2X_Q_FLG_TPA_IPV6, ¶ms->flags) * 4273adfc5217SJeff Kirsher CLIENT_INIT_RX_DATA_TPA_EN_IPV6; 4274adfc5217SJeff Kirsher } 4275adfc5217SJeff Kirsher 4276adfc5217SJeff Kirsher static void bnx2x_q_fill_init_general_data(struct bnx2x *bp, 4277adfc5217SJeff Kirsher struct bnx2x_queue_sp_obj *o, 4278adfc5217SJeff Kirsher struct bnx2x_general_setup_params *params, 4279adfc5217SJeff Kirsher struct client_init_general_data *gen_data, 4280adfc5217SJeff Kirsher unsigned long *flags) 4281adfc5217SJeff Kirsher { 4282adfc5217SJeff Kirsher gen_data->client_id = o->cl_id; 4283adfc5217SJeff Kirsher 4284adfc5217SJeff Kirsher if (test_bit(BNX2X_Q_FLG_STATS, flags)) { 4285adfc5217SJeff Kirsher gen_data->statistics_counter_id = 4286adfc5217SJeff Kirsher params->stat_id; 4287adfc5217SJeff Kirsher gen_data->statistics_en_flg = 1; 4288adfc5217SJeff Kirsher gen_data->statistics_zero_flg = 4289adfc5217SJeff Kirsher test_bit(BNX2X_Q_FLG_ZERO_STATS, flags); 4290adfc5217SJeff Kirsher } else 4291adfc5217SJeff Kirsher gen_data->statistics_counter_id = 4292adfc5217SJeff Kirsher DISABLE_STATISTIC_COUNTER_ID_VALUE; 4293adfc5217SJeff Kirsher 4294adfc5217SJeff Kirsher gen_data->is_fcoe_flg = test_bit(BNX2X_Q_FLG_FCOE, flags); 4295adfc5217SJeff Kirsher gen_data->activate_flg = test_bit(BNX2X_Q_FLG_ACTIVE, flags); 4296adfc5217SJeff Kirsher gen_data->sp_client_id = params->spcl_id; 4297adfc5217SJeff Kirsher gen_data->mtu = cpu_to_le16(params->mtu); 4298adfc5217SJeff Kirsher gen_data->func_id = o->func_id; 4299adfc5217SJeff Kirsher 4300adfc5217SJeff Kirsher 4301adfc5217SJeff Kirsher gen_data->cos = params->cos; 4302adfc5217SJeff Kirsher 4303adfc5217SJeff Kirsher gen_data->traffic_type = 4304adfc5217SJeff Kirsher test_bit(BNX2X_Q_FLG_FCOE, flags) ? 4305adfc5217SJeff Kirsher LLFC_TRAFFIC_TYPE_FCOE : LLFC_TRAFFIC_TYPE_NW; 4306adfc5217SJeff Kirsher 430794f05b0fSJoe Perches DP(BNX2X_MSG_SP, "flags: active %d, cos %d, stats en %d\n", 4308adfc5217SJeff Kirsher gen_data->activate_flg, gen_data->cos, gen_data->statistics_en_flg); 4309adfc5217SJeff Kirsher } 4310adfc5217SJeff Kirsher 4311adfc5217SJeff Kirsher static void bnx2x_q_fill_init_tx_data(struct bnx2x_queue_sp_obj *o, 4312adfc5217SJeff Kirsher struct bnx2x_txq_setup_params *params, 4313adfc5217SJeff Kirsher struct client_init_tx_data *tx_data, 4314adfc5217SJeff Kirsher unsigned long *flags) 4315adfc5217SJeff Kirsher { 4316adfc5217SJeff Kirsher tx_data->enforce_security_flg = 4317adfc5217SJeff Kirsher test_bit(BNX2X_Q_FLG_TX_SEC, flags); 4318adfc5217SJeff Kirsher tx_data->default_vlan = 4319adfc5217SJeff Kirsher cpu_to_le16(params->default_vlan); 4320adfc5217SJeff Kirsher tx_data->default_vlan_flg = 4321adfc5217SJeff Kirsher test_bit(BNX2X_Q_FLG_DEF_VLAN, flags); 4322adfc5217SJeff Kirsher tx_data->tx_switching_flg = 4323adfc5217SJeff Kirsher test_bit(BNX2X_Q_FLG_TX_SWITCH, flags); 4324adfc5217SJeff Kirsher tx_data->anti_spoofing_flg = 4325adfc5217SJeff Kirsher test_bit(BNX2X_Q_FLG_ANTI_SPOOF, flags); 4326adfc5217SJeff Kirsher tx_data->tx_status_block_id = params->fw_sb_id; 4327adfc5217SJeff Kirsher tx_data->tx_sb_index_number = params->sb_cq_index; 4328adfc5217SJeff Kirsher tx_data->tss_leading_client_id = params->tss_leading_cl_id; 4329adfc5217SJeff Kirsher 4330adfc5217SJeff Kirsher tx_data->tx_bd_page_base.lo = 4331adfc5217SJeff Kirsher cpu_to_le32(U64_LO(params->dscr_map)); 4332adfc5217SJeff Kirsher tx_data->tx_bd_page_base.hi = 4333adfc5217SJeff Kirsher cpu_to_le32(U64_HI(params->dscr_map)); 4334adfc5217SJeff Kirsher 4335adfc5217SJeff Kirsher /* Don't configure any Tx switching mode during queue SETUP */ 4336adfc5217SJeff Kirsher tx_data->state = 0; 4337adfc5217SJeff Kirsher } 4338adfc5217SJeff Kirsher 4339adfc5217SJeff Kirsher static void bnx2x_q_fill_init_pause_data(struct bnx2x_queue_sp_obj *o, 4340adfc5217SJeff Kirsher struct rxq_pause_params *params, 4341adfc5217SJeff Kirsher struct client_init_rx_data *rx_data) 4342adfc5217SJeff Kirsher { 4343adfc5217SJeff Kirsher /* flow control data */ 4344adfc5217SJeff Kirsher rx_data->cqe_pause_thr_low = cpu_to_le16(params->rcq_th_lo); 4345adfc5217SJeff Kirsher rx_data->cqe_pause_thr_high = cpu_to_le16(params->rcq_th_hi); 4346adfc5217SJeff Kirsher rx_data->bd_pause_thr_low = cpu_to_le16(params->bd_th_lo); 4347adfc5217SJeff Kirsher rx_data->bd_pause_thr_high = cpu_to_le16(params->bd_th_hi); 4348adfc5217SJeff Kirsher rx_data->sge_pause_thr_low = cpu_to_le16(params->sge_th_lo); 4349adfc5217SJeff Kirsher rx_data->sge_pause_thr_high = cpu_to_le16(params->sge_th_hi); 4350adfc5217SJeff Kirsher rx_data->rx_cos_mask = cpu_to_le16(params->pri_map); 4351adfc5217SJeff Kirsher } 4352adfc5217SJeff Kirsher 4353adfc5217SJeff Kirsher static void bnx2x_q_fill_init_rx_data(struct bnx2x_queue_sp_obj *o, 4354adfc5217SJeff Kirsher struct bnx2x_rxq_setup_params *params, 4355adfc5217SJeff Kirsher struct client_init_rx_data *rx_data, 4356adfc5217SJeff Kirsher unsigned long *flags) 4357adfc5217SJeff Kirsher { 4358adfc5217SJeff Kirsher /* Rx data */ 4359adfc5217SJeff Kirsher rx_data->tpa_en = test_bit(BNX2X_Q_FLG_TPA, flags) * 4360adfc5217SJeff Kirsher CLIENT_INIT_RX_DATA_TPA_EN_IPV4; 4361adfc5217SJeff Kirsher rx_data->vmqueue_mode_en_flg = 0; 4362adfc5217SJeff Kirsher 4363adfc5217SJeff Kirsher rx_data->cache_line_alignment_log_size = 4364adfc5217SJeff Kirsher params->cache_line_log; 4365adfc5217SJeff Kirsher rx_data->enable_dynamic_hc = 4366adfc5217SJeff Kirsher test_bit(BNX2X_Q_FLG_DHC, flags); 4367adfc5217SJeff Kirsher rx_data->max_sges_for_packet = params->max_sges_pkt; 4368adfc5217SJeff Kirsher rx_data->client_qzone_id = params->cl_qzone_id; 4369adfc5217SJeff Kirsher rx_data->max_agg_size = cpu_to_le16(params->tpa_agg_sz); 4370adfc5217SJeff Kirsher 4371adfc5217SJeff Kirsher /* Always start in DROP_ALL mode */ 4372adfc5217SJeff Kirsher rx_data->state = cpu_to_le16(CLIENT_INIT_RX_DATA_UCAST_DROP_ALL | 4373adfc5217SJeff Kirsher CLIENT_INIT_RX_DATA_MCAST_DROP_ALL); 4374adfc5217SJeff Kirsher 4375adfc5217SJeff Kirsher /* We don't set drop flags */ 4376adfc5217SJeff Kirsher rx_data->drop_ip_cs_err_flg = 0; 4377adfc5217SJeff Kirsher rx_data->drop_tcp_cs_err_flg = 0; 4378adfc5217SJeff Kirsher rx_data->drop_ttl0_flg = 0; 4379adfc5217SJeff Kirsher rx_data->drop_udp_cs_err_flg = 0; 4380adfc5217SJeff Kirsher rx_data->inner_vlan_removal_enable_flg = 4381adfc5217SJeff Kirsher test_bit(BNX2X_Q_FLG_VLAN, flags); 4382adfc5217SJeff Kirsher rx_data->outer_vlan_removal_enable_flg = 4383adfc5217SJeff Kirsher test_bit(BNX2X_Q_FLG_OV, flags); 4384adfc5217SJeff Kirsher rx_data->status_block_id = params->fw_sb_id; 4385adfc5217SJeff Kirsher rx_data->rx_sb_index_number = params->sb_cq_index; 4386adfc5217SJeff Kirsher rx_data->max_tpa_queues = params->max_tpa_queues; 4387adfc5217SJeff Kirsher rx_data->max_bytes_on_bd = cpu_to_le16(params->buf_sz); 4388adfc5217SJeff Kirsher rx_data->sge_buff_size = cpu_to_le16(params->sge_buf_sz); 4389adfc5217SJeff Kirsher rx_data->bd_page_base.lo = 4390adfc5217SJeff Kirsher cpu_to_le32(U64_LO(params->dscr_map)); 4391adfc5217SJeff Kirsher rx_data->bd_page_base.hi = 4392adfc5217SJeff Kirsher cpu_to_le32(U64_HI(params->dscr_map)); 4393adfc5217SJeff Kirsher rx_data->sge_page_base.lo = 4394adfc5217SJeff Kirsher cpu_to_le32(U64_LO(params->sge_map)); 4395adfc5217SJeff Kirsher rx_data->sge_page_base.hi = 4396adfc5217SJeff Kirsher cpu_to_le32(U64_HI(params->sge_map)); 4397adfc5217SJeff Kirsher rx_data->cqe_page_base.lo = 4398adfc5217SJeff Kirsher cpu_to_le32(U64_LO(params->rcq_map)); 4399adfc5217SJeff Kirsher rx_data->cqe_page_base.hi = 4400adfc5217SJeff Kirsher cpu_to_le32(U64_HI(params->rcq_map)); 4401adfc5217SJeff Kirsher rx_data->is_leading_rss = test_bit(BNX2X_Q_FLG_LEADING_RSS, flags); 4402adfc5217SJeff Kirsher 4403adfc5217SJeff Kirsher if (test_bit(BNX2X_Q_FLG_MCAST, flags)) { 4404adfc5217SJeff Kirsher rx_data->approx_mcast_engine_id = o->func_id; 4405adfc5217SJeff Kirsher rx_data->is_approx_mcast = 1; 4406adfc5217SJeff Kirsher } 4407adfc5217SJeff Kirsher 4408adfc5217SJeff Kirsher rx_data->rss_engine_id = params->rss_engine_id; 4409adfc5217SJeff Kirsher 4410adfc5217SJeff Kirsher /* silent vlan removal */ 4411adfc5217SJeff Kirsher rx_data->silent_vlan_removal_flg = 4412adfc5217SJeff Kirsher test_bit(BNX2X_Q_FLG_SILENT_VLAN_REM, flags); 4413adfc5217SJeff Kirsher rx_data->silent_vlan_value = 4414adfc5217SJeff Kirsher cpu_to_le16(params->silent_removal_value); 4415adfc5217SJeff Kirsher rx_data->silent_vlan_mask = 4416adfc5217SJeff Kirsher cpu_to_le16(params->silent_removal_mask); 4417adfc5217SJeff Kirsher 4418adfc5217SJeff Kirsher } 4419adfc5217SJeff Kirsher 4420adfc5217SJeff Kirsher /* initialize the general, tx and rx parts of a queue object */ 4421adfc5217SJeff Kirsher static void bnx2x_q_fill_setup_data_cmn(struct bnx2x *bp, 4422adfc5217SJeff Kirsher struct bnx2x_queue_state_params *cmd_params, 4423adfc5217SJeff Kirsher struct client_init_ramrod_data *data) 4424adfc5217SJeff Kirsher { 4425adfc5217SJeff Kirsher bnx2x_q_fill_init_general_data(bp, cmd_params->q_obj, 4426adfc5217SJeff Kirsher &cmd_params->params.setup.gen_params, 4427adfc5217SJeff Kirsher &data->general, 4428adfc5217SJeff Kirsher &cmd_params->params.setup.flags); 4429adfc5217SJeff Kirsher 4430adfc5217SJeff Kirsher bnx2x_q_fill_init_tx_data(cmd_params->q_obj, 4431adfc5217SJeff Kirsher &cmd_params->params.setup.txq_params, 4432adfc5217SJeff Kirsher &data->tx, 4433adfc5217SJeff Kirsher &cmd_params->params.setup.flags); 4434adfc5217SJeff Kirsher 4435adfc5217SJeff Kirsher bnx2x_q_fill_init_rx_data(cmd_params->q_obj, 4436adfc5217SJeff Kirsher &cmd_params->params.setup.rxq_params, 4437adfc5217SJeff Kirsher &data->rx, 4438adfc5217SJeff Kirsher &cmd_params->params.setup.flags); 4439adfc5217SJeff Kirsher 4440adfc5217SJeff Kirsher bnx2x_q_fill_init_pause_data(cmd_params->q_obj, 4441adfc5217SJeff Kirsher &cmd_params->params.setup.pause_params, 4442adfc5217SJeff Kirsher &data->rx); 4443adfc5217SJeff Kirsher } 4444adfc5217SJeff Kirsher 4445adfc5217SJeff Kirsher /* initialize the general and tx parts of a tx-only queue object */ 4446adfc5217SJeff Kirsher static void bnx2x_q_fill_setup_tx_only(struct bnx2x *bp, 4447adfc5217SJeff Kirsher struct bnx2x_queue_state_params *cmd_params, 4448adfc5217SJeff Kirsher struct tx_queue_init_ramrod_data *data) 4449adfc5217SJeff Kirsher { 4450adfc5217SJeff Kirsher bnx2x_q_fill_init_general_data(bp, cmd_params->q_obj, 4451adfc5217SJeff Kirsher &cmd_params->params.tx_only.gen_params, 4452adfc5217SJeff Kirsher &data->general, 4453adfc5217SJeff Kirsher &cmd_params->params.tx_only.flags); 4454adfc5217SJeff Kirsher 4455adfc5217SJeff Kirsher bnx2x_q_fill_init_tx_data(cmd_params->q_obj, 4456adfc5217SJeff Kirsher &cmd_params->params.tx_only.txq_params, 4457adfc5217SJeff Kirsher &data->tx, 4458adfc5217SJeff Kirsher &cmd_params->params.tx_only.flags); 4459adfc5217SJeff Kirsher 446094f05b0fSJoe Perches DP(BNX2X_MSG_SP, "cid %d, tx bd page lo %x hi %x\n",cmd_params->q_obj->cids[0], 4461adfc5217SJeff Kirsher data->tx.tx_bd_page_base.lo, data->tx.tx_bd_page_base.hi); 4462adfc5217SJeff Kirsher } 4463adfc5217SJeff Kirsher 4464adfc5217SJeff Kirsher /** 4465adfc5217SJeff Kirsher * bnx2x_q_init - init HW/FW queue 4466adfc5217SJeff Kirsher * 4467adfc5217SJeff Kirsher * @bp: device handle 4468adfc5217SJeff Kirsher * @params: 4469adfc5217SJeff Kirsher * 4470adfc5217SJeff Kirsher * HW/FW initial Queue configuration: 4471adfc5217SJeff Kirsher * - HC: Rx and Tx 4472adfc5217SJeff Kirsher * - CDU context validation 4473adfc5217SJeff Kirsher * 4474adfc5217SJeff Kirsher */ 4475adfc5217SJeff Kirsher static inline int bnx2x_q_init(struct bnx2x *bp, 4476adfc5217SJeff Kirsher struct bnx2x_queue_state_params *params) 4477adfc5217SJeff Kirsher { 4478adfc5217SJeff Kirsher struct bnx2x_queue_sp_obj *o = params->q_obj; 4479adfc5217SJeff Kirsher struct bnx2x_queue_init_params *init = ¶ms->params.init; 4480adfc5217SJeff Kirsher u16 hc_usec; 4481adfc5217SJeff Kirsher u8 cos; 4482adfc5217SJeff Kirsher 4483adfc5217SJeff Kirsher /* Tx HC configuration */ 4484adfc5217SJeff Kirsher if (test_bit(BNX2X_Q_TYPE_HAS_TX, &o->type) && 4485adfc5217SJeff Kirsher test_bit(BNX2X_Q_FLG_HC, &init->tx.flags)) { 4486adfc5217SJeff Kirsher hc_usec = init->tx.hc_rate ? 1000000 / init->tx.hc_rate : 0; 4487adfc5217SJeff Kirsher 4488adfc5217SJeff Kirsher bnx2x_update_coalesce_sb_index(bp, init->tx.fw_sb_id, 4489adfc5217SJeff Kirsher init->tx.sb_cq_index, 4490adfc5217SJeff Kirsher !test_bit(BNX2X_Q_FLG_HC_EN, &init->tx.flags), 4491adfc5217SJeff Kirsher hc_usec); 4492adfc5217SJeff Kirsher } 4493adfc5217SJeff Kirsher 4494adfc5217SJeff Kirsher /* Rx HC configuration */ 4495adfc5217SJeff Kirsher if (test_bit(BNX2X_Q_TYPE_HAS_RX, &o->type) && 4496adfc5217SJeff Kirsher test_bit(BNX2X_Q_FLG_HC, &init->rx.flags)) { 4497adfc5217SJeff Kirsher hc_usec = init->rx.hc_rate ? 1000000 / init->rx.hc_rate : 0; 4498adfc5217SJeff Kirsher 4499adfc5217SJeff Kirsher bnx2x_update_coalesce_sb_index(bp, init->rx.fw_sb_id, 4500adfc5217SJeff Kirsher init->rx.sb_cq_index, 4501adfc5217SJeff Kirsher !test_bit(BNX2X_Q_FLG_HC_EN, &init->rx.flags), 4502adfc5217SJeff Kirsher hc_usec); 4503adfc5217SJeff Kirsher } 4504adfc5217SJeff Kirsher 4505adfc5217SJeff Kirsher /* Set CDU context validation values */ 4506adfc5217SJeff Kirsher for (cos = 0; cos < o->max_cos; cos++) { 450794f05b0fSJoe Perches DP(BNX2X_MSG_SP, "setting context validation. cid %d, cos %d\n", 4508adfc5217SJeff Kirsher o->cids[cos], cos); 450994f05b0fSJoe Perches DP(BNX2X_MSG_SP, "context pointer %p\n", init->cxts[cos]); 4510adfc5217SJeff Kirsher bnx2x_set_ctx_validation(bp, init->cxts[cos], o->cids[cos]); 4511adfc5217SJeff Kirsher } 4512adfc5217SJeff Kirsher 4513adfc5217SJeff Kirsher /* As no ramrod is sent, complete the command immediately */ 4514adfc5217SJeff Kirsher o->complete_cmd(bp, o, BNX2X_Q_CMD_INIT); 4515adfc5217SJeff Kirsher 4516adfc5217SJeff Kirsher mmiowb(); 4517adfc5217SJeff Kirsher smp_mb(); 4518adfc5217SJeff Kirsher 4519adfc5217SJeff Kirsher return 0; 4520adfc5217SJeff Kirsher } 4521adfc5217SJeff Kirsher 4522adfc5217SJeff Kirsher static inline int bnx2x_q_send_setup_e1x(struct bnx2x *bp, 4523adfc5217SJeff Kirsher struct bnx2x_queue_state_params *params) 4524adfc5217SJeff Kirsher { 4525adfc5217SJeff Kirsher struct bnx2x_queue_sp_obj *o = params->q_obj; 4526adfc5217SJeff Kirsher struct client_init_ramrod_data *rdata = 4527adfc5217SJeff Kirsher (struct client_init_ramrod_data *)o->rdata; 4528adfc5217SJeff Kirsher dma_addr_t data_mapping = o->rdata_mapping; 4529adfc5217SJeff Kirsher int ramrod = RAMROD_CMD_ID_ETH_CLIENT_SETUP; 4530adfc5217SJeff Kirsher 4531adfc5217SJeff Kirsher /* Clear the ramrod data */ 4532adfc5217SJeff Kirsher memset(rdata, 0, sizeof(*rdata)); 4533adfc5217SJeff Kirsher 4534adfc5217SJeff Kirsher /* Fill the ramrod data */ 4535adfc5217SJeff Kirsher bnx2x_q_fill_setup_data_cmn(bp, params, rdata); 4536adfc5217SJeff Kirsher 4537adfc5217SJeff Kirsher /* 4538adfc5217SJeff Kirsher * No need for an explicit memory barrier here as long we would 4539adfc5217SJeff Kirsher * need to ensure the ordering of writing to the SPQ element 4540adfc5217SJeff Kirsher * and updating of the SPQ producer which involves a memory 4541adfc5217SJeff Kirsher * read and we will have to put a full memory barrier there 4542adfc5217SJeff Kirsher * (inside bnx2x_sp_post()). 4543adfc5217SJeff Kirsher */ 4544adfc5217SJeff Kirsher 4545adfc5217SJeff Kirsher return bnx2x_sp_post(bp, ramrod, o->cids[BNX2X_PRIMARY_CID_INDEX], 4546adfc5217SJeff Kirsher U64_HI(data_mapping), 4547adfc5217SJeff Kirsher U64_LO(data_mapping), ETH_CONNECTION_TYPE); 4548adfc5217SJeff Kirsher } 4549adfc5217SJeff Kirsher 4550adfc5217SJeff Kirsher static inline int bnx2x_q_send_setup_e2(struct bnx2x *bp, 4551adfc5217SJeff Kirsher struct bnx2x_queue_state_params *params) 4552adfc5217SJeff Kirsher { 4553adfc5217SJeff Kirsher struct bnx2x_queue_sp_obj *o = params->q_obj; 4554adfc5217SJeff Kirsher struct client_init_ramrod_data *rdata = 4555adfc5217SJeff Kirsher (struct client_init_ramrod_data *)o->rdata; 4556adfc5217SJeff Kirsher dma_addr_t data_mapping = o->rdata_mapping; 4557adfc5217SJeff Kirsher int ramrod = RAMROD_CMD_ID_ETH_CLIENT_SETUP; 4558adfc5217SJeff Kirsher 4559adfc5217SJeff Kirsher /* Clear the ramrod data */ 4560adfc5217SJeff Kirsher memset(rdata, 0, sizeof(*rdata)); 4561adfc5217SJeff Kirsher 4562adfc5217SJeff Kirsher /* Fill the ramrod data */ 4563adfc5217SJeff Kirsher bnx2x_q_fill_setup_data_cmn(bp, params, rdata); 4564adfc5217SJeff Kirsher bnx2x_q_fill_setup_data_e2(bp, params, rdata); 4565adfc5217SJeff Kirsher 4566adfc5217SJeff Kirsher /* 4567adfc5217SJeff Kirsher * No need for an explicit memory barrier here as long we would 4568adfc5217SJeff Kirsher * need to ensure the ordering of writing to the SPQ element 4569adfc5217SJeff Kirsher * and updating of the SPQ producer which involves a memory 4570adfc5217SJeff Kirsher * read and we will have to put a full memory barrier there 4571adfc5217SJeff Kirsher * (inside bnx2x_sp_post()). 4572adfc5217SJeff Kirsher */ 4573adfc5217SJeff Kirsher 4574adfc5217SJeff Kirsher return bnx2x_sp_post(bp, ramrod, o->cids[BNX2X_PRIMARY_CID_INDEX], 4575adfc5217SJeff Kirsher U64_HI(data_mapping), 4576adfc5217SJeff Kirsher U64_LO(data_mapping), ETH_CONNECTION_TYPE); 4577adfc5217SJeff Kirsher } 4578adfc5217SJeff Kirsher 4579adfc5217SJeff Kirsher static inline int bnx2x_q_send_setup_tx_only(struct bnx2x *bp, 4580adfc5217SJeff Kirsher struct bnx2x_queue_state_params *params) 4581adfc5217SJeff Kirsher { 4582adfc5217SJeff Kirsher struct bnx2x_queue_sp_obj *o = params->q_obj; 4583adfc5217SJeff Kirsher struct tx_queue_init_ramrod_data *rdata = 4584adfc5217SJeff Kirsher (struct tx_queue_init_ramrod_data *)o->rdata; 4585adfc5217SJeff Kirsher dma_addr_t data_mapping = o->rdata_mapping; 4586adfc5217SJeff Kirsher int ramrod = RAMROD_CMD_ID_ETH_TX_QUEUE_SETUP; 4587adfc5217SJeff Kirsher struct bnx2x_queue_setup_tx_only_params *tx_only_params = 4588adfc5217SJeff Kirsher ¶ms->params.tx_only; 4589adfc5217SJeff Kirsher u8 cid_index = tx_only_params->cid_index; 4590adfc5217SJeff Kirsher 4591adfc5217SJeff Kirsher 4592adfc5217SJeff Kirsher if (cid_index >= o->max_cos) { 4593adfc5217SJeff Kirsher BNX2X_ERR("queue[%d]: cid_index (%d) is out of range\n", 4594adfc5217SJeff Kirsher o->cl_id, cid_index); 4595adfc5217SJeff Kirsher return -EINVAL; 4596adfc5217SJeff Kirsher } 4597adfc5217SJeff Kirsher 459894f05b0fSJoe Perches DP(BNX2X_MSG_SP, "parameters received: cos: %d sp-id: %d\n", 4599adfc5217SJeff Kirsher tx_only_params->gen_params.cos, 4600adfc5217SJeff Kirsher tx_only_params->gen_params.spcl_id); 4601adfc5217SJeff Kirsher 4602adfc5217SJeff Kirsher /* Clear the ramrod data */ 4603adfc5217SJeff Kirsher memset(rdata, 0, sizeof(*rdata)); 4604adfc5217SJeff Kirsher 4605adfc5217SJeff Kirsher /* Fill the ramrod data */ 4606adfc5217SJeff Kirsher bnx2x_q_fill_setup_tx_only(bp, params, rdata); 4607adfc5217SJeff Kirsher 4608adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "sending tx-only ramrod: cid %d, client-id %d," 460994f05b0fSJoe Perches "sp-client id %d, cos %d\n", 4610adfc5217SJeff Kirsher o->cids[cid_index], 4611adfc5217SJeff Kirsher rdata->general.client_id, 4612adfc5217SJeff Kirsher rdata->general.sp_client_id, rdata->general.cos); 4613adfc5217SJeff Kirsher 4614adfc5217SJeff Kirsher /* 4615adfc5217SJeff Kirsher * No need for an explicit memory barrier here as long we would 4616adfc5217SJeff Kirsher * need to ensure the ordering of writing to the SPQ element 4617adfc5217SJeff Kirsher * and updating of the SPQ producer which involves a memory 4618adfc5217SJeff Kirsher * read and we will have to put a full memory barrier there 4619adfc5217SJeff Kirsher * (inside bnx2x_sp_post()). 4620adfc5217SJeff Kirsher */ 4621adfc5217SJeff Kirsher 4622adfc5217SJeff Kirsher return bnx2x_sp_post(bp, ramrod, o->cids[cid_index], 4623adfc5217SJeff Kirsher U64_HI(data_mapping), 4624adfc5217SJeff Kirsher U64_LO(data_mapping), ETH_CONNECTION_TYPE); 4625adfc5217SJeff Kirsher } 4626adfc5217SJeff Kirsher 4627adfc5217SJeff Kirsher static void bnx2x_q_fill_update_data(struct bnx2x *bp, 4628adfc5217SJeff Kirsher struct bnx2x_queue_sp_obj *obj, 4629adfc5217SJeff Kirsher struct bnx2x_queue_update_params *params, 4630adfc5217SJeff Kirsher struct client_update_ramrod_data *data) 4631adfc5217SJeff Kirsher { 4632adfc5217SJeff Kirsher /* Client ID of the client to update */ 4633adfc5217SJeff Kirsher data->client_id = obj->cl_id; 4634adfc5217SJeff Kirsher 4635adfc5217SJeff Kirsher /* Function ID of the client to update */ 4636adfc5217SJeff Kirsher data->func_id = obj->func_id; 4637adfc5217SJeff Kirsher 4638adfc5217SJeff Kirsher /* Default VLAN value */ 4639adfc5217SJeff Kirsher data->default_vlan = cpu_to_le16(params->def_vlan); 4640adfc5217SJeff Kirsher 4641adfc5217SJeff Kirsher /* Inner VLAN stripping */ 4642adfc5217SJeff Kirsher data->inner_vlan_removal_enable_flg = 4643adfc5217SJeff Kirsher test_bit(BNX2X_Q_UPDATE_IN_VLAN_REM, ¶ms->update_flags); 4644adfc5217SJeff Kirsher data->inner_vlan_removal_change_flg = 4645adfc5217SJeff Kirsher test_bit(BNX2X_Q_UPDATE_IN_VLAN_REM_CHNG, 4646adfc5217SJeff Kirsher ¶ms->update_flags); 4647adfc5217SJeff Kirsher 4648adfc5217SJeff Kirsher /* Outer VLAN sripping */ 4649adfc5217SJeff Kirsher data->outer_vlan_removal_enable_flg = 4650adfc5217SJeff Kirsher test_bit(BNX2X_Q_UPDATE_OUT_VLAN_REM, ¶ms->update_flags); 4651adfc5217SJeff Kirsher data->outer_vlan_removal_change_flg = 4652adfc5217SJeff Kirsher test_bit(BNX2X_Q_UPDATE_OUT_VLAN_REM_CHNG, 4653adfc5217SJeff Kirsher ¶ms->update_flags); 4654adfc5217SJeff Kirsher 4655adfc5217SJeff Kirsher /* Drop packets that have source MAC that doesn't belong to this 4656adfc5217SJeff Kirsher * Queue. 4657adfc5217SJeff Kirsher */ 4658adfc5217SJeff Kirsher data->anti_spoofing_enable_flg = 4659adfc5217SJeff Kirsher test_bit(BNX2X_Q_UPDATE_ANTI_SPOOF, ¶ms->update_flags); 4660adfc5217SJeff Kirsher data->anti_spoofing_change_flg = 4661adfc5217SJeff Kirsher test_bit(BNX2X_Q_UPDATE_ANTI_SPOOF_CHNG, ¶ms->update_flags); 4662adfc5217SJeff Kirsher 4663adfc5217SJeff Kirsher /* Activate/Deactivate */ 4664adfc5217SJeff Kirsher data->activate_flg = 4665adfc5217SJeff Kirsher test_bit(BNX2X_Q_UPDATE_ACTIVATE, ¶ms->update_flags); 4666adfc5217SJeff Kirsher data->activate_change_flg = 4667adfc5217SJeff Kirsher test_bit(BNX2X_Q_UPDATE_ACTIVATE_CHNG, ¶ms->update_flags); 4668adfc5217SJeff Kirsher 4669adfc5217SJeff Kirsher /* Enable default VLAN */ 4670adfc5217SJeff Kirsher data->default_vlan_enable_flg = 4671adfc5217SJeff Kirsher test_bit(BNX2X_Q_UPDATE_DEF_VLAN_EN, ¶ms->update_flags); 4672adfc5217SJeff Kirsher data->default_vlan_change_flg = 4673adfc5217SJeff Kirsher test_bit(BNX2X_Q_UPDATE_DEF_VLAN_EN_CHNG, 4674adfc5217SJeff Kirsher ¶ms->update_flags); 4675adfc5217SJeff Kirsher 4676adfc5217SJeff Kirsher /* silent vlan removal */ 4677adfc5217SJeff Kirsher data->silent_vlan_change_flg = 4678adfc5217SJeff Kirsher test_bit(BNX2X_Q_UPDATE_SILENT_VLAN_REM_CHNG, 4679adfc5217SJeff Kirsher ¶ms->update_flags); 4680adfc5217SJeff Kirsher data->silent_vlan_removal_flg = 4681adfc5217SJeff Kirsher test_bit(BNX2X_Q_UPDATE_SILENT_VLAN_REM, ¶ms->update_flags); 4682adfc5217SJeff Kirsher data->silent_vlan_value = cpu_to_le16(params->silent_removal_value); 4683adfc5217SJeff Kirsher data->silent_vlan_mask = cpu_to_le16(params->silent_removal_mask); 4684adfc5217SJeff Kirsher } 4685adfc5217SJeff Kirsher 4686adfc5217SJeff Kirsher static inline int bnx2x_q_send_update(struct bnx2x *bp, 4687adfc5217SJeff Kirsher struct bnx2x_queue_state_params *params) 4688adfc5217SJeff Kirsher { 4689adfc5217SJeff Kirsher struct bnx2x_queue_sp_obj *o = params->q_obj; 4690adfc5217SJeff Kirsher struct client_update_ramrod_data *rdata = 4691adfc5217SJeff Kirsher (struct client_update_ramrod_data *)o->rdata; 4692adfc5217SJeff Kirsher dma_addr_t data_mapping = o->rdata_mapping; 4693adfc5217SJeff Kirsher struct bnx2x_queue_update_params *update_params = 4694adfc5217SJeff Kirsher ¶ms->params.update; 4695adfc5217SJeff Kirsher u8 cid_index = update_params->cid_index; 4696adfc5217SJeff Kirsher 4697adfc5217SJeff Kirsher if (cid_index >= o->max_cos) { 4698adfc5217SJeff Kirsher BNX2X_ERR("queue[%d]: cid_index (%d) is out of range\n", 4699adfc5217SJeff Kirsher o->cl_id, cid_index); 4700adfc5217SJeff Kirsher return -EINVAL; 4701adfc5217SJeff Kirsher } 4702adfc5217SJeff Kirsher 4703adfc5217SJeff Kirsher 4704adfc5217SJeff Kirsher /* Clear the ramrod data */ 4705adfc5217SJeff Kirsher memset(rdata, 0, sizeof(*rdata)); 4706adfc5217SJeff Kirsher 4707adfc5217SJeff Kirsher /* Fill the ramrod data */ 4708adfc5217SJeff Kirsher bnx2x_q_fill_update_data(bp, o, update_params, rdata); 4709adfc5217SJeff Kirsher 4710adfc5217SJeff Kirsher /* 4711adfc5217SJeff Kirsher * No need for an explicit memory barrier here as long we would 4712adfc5217SJeff Kirsher * need to ensure the ordering of writing to the SPQ element 4713adfc5217SJeff Kirsher * and updating of the SPQ producer which involves a memory 4714adfc5217SJeff Kirsher * read and we will have to put a full memory barrier there 4715adfc5217SJeff Kirsher * (inside bnx2x_sp_post()). 4716adfc5217SJeff Kirsher */ 4717adfc5217SJeff Kirsher 4718adfc5217SJeff Kirsher return bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_UPDATE, 4719adfc5217SJeff Kirsher o->cids[cid_index], U64_HI(data_mapping), 4720adfc5217SJeff Kirsher U64_LO(data_mapping), ETH_CONNECTION_TYPE); 4721adfc5217SJeff Kirsher } 4722adfc5217SJeff Kirsher 4723adfc5217SJeff Kirsher /** 4724adfc5217SJeff Kirsher * bnx2x_q_send_deactivate - send DEACTIVATE command 4725adfc5217SJeff Kirsher * 4726adfc5217SJeff Kirsher * @bp: device handle 4727adfc5217SJeff Kirsher * @params: 4728adfc5217SJeff Kirsher * 4729adfc5217SJeff Kirsher * implemented using the UPDATE command. 4730adfc5217SJeff Kirsher */ 4731adfc5217SJeff Kirsher static inline int bnx2x_q_send_deactivate(struct bnx2x *bp, 4732adfc5217SJeff Kirsher struct bnx2x_queue_state_params *params) 4733adfc5217SJeff Kirsher { 4734adfc5217SJeff Kirsher struct bnx2x_queue_update_params *update = ¶ms->params.update; 4735adfc5217SJeff Kirsher 4736adfc5217SJeff Kirsher memset(update, 0, sizeof(*update)); 4737adfc5217SJeff Kirsher 4738adfc5217SJeff Kirsher __set_bit(BNX2X_Q_UPDATE_ACTIVATE_CHNG, &update->update_flags); 4739adfc5217SJeff Kirsher 4740adfc5217SJeff Kirsher return bnx2x_q_send_update(bp, params); 4741adfc5217SJeff Kirsher } 4742adfc5217SJeff Kirsher 4743adfc5217SJeff Kirsher /** 4744adfc5217SJeff Kirsher * bnx2x_q_send_activate - send ACTIVATE command 4745adfc5217SJeff Kirsher * 4746adfc5217SJeff Kirsher * @bp: device handle 4747adfc5217SJeff Kirsher * @params: 4748adfc5217SJeff Kirsher * 4749adfc5217SJeff Kirsher * implemented using the UPDATE command. 4750adfc5217SJeff Kirsher */ 4751adfc5217SJeff Kirsher static inline int bnx2x_q_send_activate(struct bnx2x *bp, 4752adfc5217SJeff Kirsher struct bnx2x_queue_state_params *params) 4753adfc5217SJeff Kirsher { 4754adfc5217SJeff Kirsher struct bnx2x_queue_update_params *update = ¶ms->params.update; 4755adfc5217SJeff Kirsher 4756adfc5217SJeff Kirsher memset(update, 0, sizeof(*update)); 4757adfc5217SJeff Kirsher 4758adfc5217SJeff Kirsher __set_bit(BNX2X_Q_UPDATE_ACTIVATE, &update->update_flags); 4759adfc5217SJeff Kirsher __set_bit(BNX2X_Q_UPDATE_ACTIVATE_CHNG, &update->update_flags); 4760adfc5217SJeff Kirsher 4761adfc5217SJeff Kirsher return bnx2x_q_send_update(bp, params); 4762adfc5217SJeff Kirsher } 4763adfc5217SJeff Kirsher 4764adfc5217SJeff Kirsher static inline int bnx2x_q_send_update_tpa(struct bnx2x *bp, 4765adfc5217SJeff Kirsher struct bnx2x_queue_state_params *params) 4766adfc5217SJeff Kirsher { 4767adfc5217SJeff Kirsher /* TODO: Not implemented yet. */ 4768adfc5217SJeff Kirsher return -1; 4769adfc5217SJeff Kirsher } 4770adfc5217SJeff Kirsher 4771adfc5217SJeff Kirsher static inline int bnx2x_q_send_halt(struct bnx2x *bp, 4772adfc5217SJeff Kirsher struct bnx2x_queue_state_params *params) 4773adfc5217SJeff Kirsher { 4774adfc5217SJeff Kirsher struct bnx2x_queue_sp_obj *o = params->q_obj; 4775adfc5217SJeff Kirsher 4776adfc5217SJeff Kirsher return bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, 4777adfc5217SJeff Kirsher o->cids[BNX2X_PRIMARY_CID_INDEX], 0, o->cl_id, 4778adfc5217SJeff Kirsher ETH_CONNECTION_TYPE); 4779adfc5217SJeff Kirsher } 4780adfc5217SJeff Kirsher 4781adfc5217SJeff Kirsher static inline int bnx2x_q_send_cfc_del(struct bnx2x *bp, 4782adfc5217SJeff Kirsher struct bnx2x_queue_state_params *params) 4783adfc5217SJeff Kirsher { 4784adfc5217SJeff Kirsher struct bnx2x_queue_sp_obj *o = params->q_obj; 4785adfc5217SJeff Kirsher u8 cid_idx = params->params.cfc_del.cid_index; 4786adfc5217SJeff Kirsher 4787adfc5217SJeff Kirsher if (cid_idx >= o->max_cos) { 4788adfc5217SJeff Kirsher BNX2X_ERR("queue[%d]: cid_index (%d) is out of range\n", 4789adfc5217SJeff Kirsher o->cl_id, cid_idx); 4790adfc5217SJeff Kirsher return -EINVAL; 4791adfc5217SJeff Kirsher } 4792adfc5217SJeff Kirsher 4793adfc5217SJeff Kirsher return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_CFC_DEL, 4794adfc5217SJeff Kirsher o->cids[cid_idx], 0, 0, NONE_CONNECTION_TYPE); 4795adfc5217SJeff Kirsher } 4796adfc5217SJeff Kirsher 4797adfc5217SJeff Kirsher static inline int bnx2x_q_send_terminate(struct bnx2x *bp, 4798adfc5217SJeff Kirsher struct bnx2x_queue_state_params *params) 4799adfc5217SJeff Kirsher { 4800adfc5217SJeff Kirsher struct bnx2x_queue_sp_obj *o = params->q_obj; 4801adfc5217SJeff Kirsher u8 cid_index = params->params.terminate.cid_index; 4802adfc5217SJeff Kirsher 4803adfc5217SJeff Kirsher if (cid_index >= o->max_cos) { 4804adfc5217SJeff Kirsher BNX2X_ERR("queue[%d]: cid_index (%d) is out of range\n", 4805adfc5217SJeff Kirsher o->cl_id, cid_index); 4806adfc5217SJeff Kirsher return -EINVAL; 4807adfc5217SJeff Kirsher } 4808adfc5217SJeff Kirsher 4809adfc5217SJeff Kirsher return bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_TERMINATE, 4810adfc5217SJeff Kirsher o->cids[cid_index], 0, 0, ETH_CONNECTION_TYPE); 4811adfc5217SJeff Kirsher } 4812adfc5217SJeff Kirsher 4813adfc5217SJeff Kirsher static inline int bnx2x_q_send_empty(struct bnx2x *bp, 4814adfc5217SJeff Kirsher struct bnx2x_queue_state_params *params) 4815adfc5217SJeff Kirsher { 4816adfc5217SJeff Kirsher struct bnx2x_queue_sp_obj *o = params->q_obj; 4817adfc5217SJeff Kirsher 4818adfc5217SJeff Kirsher return bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_EMPTY, 4819adfc5217SJeff Kirsher o->cids[BNX2X_PRIMARY_CID_INDEX], 0, 0, 4820adfc5217SJeff Kirsher ETH_CONNECTION_TYPE); 4821adfc5217SJeff Kirsher } 4822adfc5217SJeff Kirsher 4823adfc5217SJeff Kirsher static inline int bnx2x_queue_send_cmd_cmn(struct bnx2x *bp, 4824adfc5217SJeff Kirsher struct bnx2x_queue_state_params *params) 4825adfc5217SJeff Kirsher { 4826adfc5217SJeff Kirsher switch (params->cmd) { 4827adfc5217SJeff Kirsher case BNX2X_Q_CMD_INIT: 4828adfc5217SJeff Kirsher return bnx2x_q_init(bp, params); 4829adfc5217SJeff Kirsher case BNX2X_Q_CMD_SETUP_TX_ONLY: 4830adfc5217SJeff Kirsher return bnx2x_q_send_setup_tx_only(bp, params); 4831adfc5217SJeff Kirsher case BNX2X_Q_CMD_DEACTIVATE: 4832adfc5217SJeff Kirsher return bnx2x_q_send_deactivate(bp, params); 4833adfc5217SJeff Kirsher case BNX2X_Q_CMD_ACTIVATE: 4834adfc5217SJeff Kirsher return bnx2x_q_send_activate(bp, params); 4835adfc5217SJeff Kirsher case BNX2X_Q_CMD_UPDATE: 4836adfc5217SJeff Kirsher return bnx2x_q_send_update(bp, params); 4837adfc5217SJeff Kirsher case BNX2X_Q_CMD_UPDATE_TPA: 4838adfc5217SJeff Kirsher return bnx2x_q_send_update_tpa(bp, params); 4839adfc5217SJeff Kirsher case BNX2X_Q_CMD_HALT: 4840adfc5217SJeff Kirsher return bnx2x_q_send_halt(bp, params); 4841adfc5217SJeff Kirsher case BNX2X_Q_CMD_CFC_DEL: 4842adfc5217SJeff Kirsher return bnx2x_q_send_cfc_del(bp, params); 4843adfc5217SJeff Kirsher case BNX2X_Q_CMD_TERMINATE: 4844adfc5217SJeff Kirsher return bnx2x_q_send_terminate(bp, params); 4845adfc5217SJeff Kirsher case BNX2X_Q_CMD_EMPTY: 4846adfc5217SJeff Kirsher return bnx2x_q_send_empty(bp, params); 4847adfc5217SJeff Kirsher default: 4848adfc5217SJeff Kirsher BNX2X_ERR("Unknown command: %d\n", params->cmd); 4849adfc5217SJeff Kirsher return -EINVAL; 4850adfc5217SJeff Kirsher } 4851adfc5217SJeff Kirsher } 4852adfc5217SJeff Kirsher 4853adfc5217SJeff Kirsher static int bnx2x_queue_send_cmd_e1x(struct bnx2x *bp, 4854adfc5217SJeff Kirsher struct bnx2x_queue_state_params *params) 4855adfc5217SJeff Kirsher { 4856adfc5217SJeff Kirsher switch (params->cmd) { 4857adfc5217SJeff Kirsher case BNX2X_Q_CMD_SETUP: 4858adfc5217SJeff Kirsher return bnx2x_q_send_setup_e1x(bp, params); 4859adfc5217SJeff Kirsher case BNX2X_Q_CMD_INIT: 4860adfc5217SJeff Kirsher case BNX2X_Q_CMD_SETUP_TX_ONLY: 4861adfc5217SJeff Kirsher case BNX2X_Q_CMD_DEACTIVATE: 4862adfc5217SJeff Kirsher case BNX2X_Q_CMD_ACTIVATE: 4863adfc5217SJeff Kirsher case BNX2X_Q_CMD_UPDATE: 4864adfc5217SJeff Kirsher case BNX2X_Q_CMD_UPDATE_TPA: 4865adfc5217SJeff Kirsher case BNX2X_Q_CMD_HALT: 4866adfc5217SJeff Kirsher case BNX2X_Q_CMD_CFC_DEL: 4867adfc5217SJeff Kirsher case BNX2X_Q_CMD_TERMINATE: 4868adfc5217SJeff Kirsher case BNX2X_Q_CMD_EMPTY: 4869adfc5217SJeff Kirsher return bnx2x_queue_send_cmd_cmn(bp, params); 4870adfc5217SJeff Kirsher default: 4871adfc5217SJeff Kirsher BNX2X_ERR("Unknown command: %d\n", params->cmd); 4872adfc5217SJeff Kirsher return -EINVAL; 4873adfc5217SJeff Kirsher } 4874adfc5217SJeff Kirsher } 4875adfc5217SJeff Kirsher 4876adfc5217SJeff Kirsher static int bnx2x_queue_send_cmd_e2(struct bnx2x *bp, 4877adfc5217SJeff Kirsher struct bnx2x_queue_state_params *params) 4878adfc5217SJeff Kirsher { 4879adfc5217SJeff Kirsher switch (params->cmd) { 4880adfc5217SJeff Kirsher case BNX2X_Q_CMD_SETUP: 4881adfc5217SJeff Kirsher return bnx2x_q_send_setup_e2(bp, params); 4882adfc5217SJeff Kirsher case BNX2X_Q_CMD_INIT: 4883adfc5217SJeff Kirsher case BNX2X_Q_CMD_SETUP_TX_ONLY: 4884adfc5217SJeff Kirsher case BNX2X_Q_CMD_DEACTIVATE: 4885adfc5217SJeff Kirsher case BNX2X_Q_CMD_ACTIVATE: 4886adfc5217SJeff Kirsher case BNX2X_Q_CMD_UPDATE: 4887adfc5217SJeff Kirsher case BNX2X_Q_CMD_UPDATE_TPA: 4888adfc5217SJeff Kirsher case BNX2X_Q_CMD_HALT: 4889adfc5217SJeff Kirsher case BNX2X_Q_CMD_CFC_DEL: 4890adfc5217SJeff Kirsher case BNX2X_Q_CMD_TERMINATE: 4891adfc5217SJeff Kirsher case BNX2X_Q_CMD_EMPTY: 4892adfc5217SJeff Kirsher return bnx2x_queue_send_cmd_cmn(bp, params); 4893adfc5217SJeff Kirsher default: 4894adfc5217SJeff Kirsher BNX2X_ERR("Unknown command: %d\n", params->cmd); 4895adfc5217SJeff Kirsher return -EINVAL; 4896adfc5217SJeff Kirsher } 4897adfc5217SJeff Kirsher } 4898adfc5217SJeff Kirsher 4899adfc5217SJeff Kirsher /** 4900adfc5217SJeff Kirsher * bnx2x_queue_chk_transition - check state machine of a regular Queue 4901adfc5217SJeff Kirsher * 4902adfc5217SJeff Kirsher * @bp: device handle 4903adfc5217SJeff Kirsher * @o: 4904adfc5217SJeff Kirsher * @params: 4905adfc5217SJeff Kirsher * 4906adfc5217SJeff Kirsher * (not Forwarding) 4907adfc5217SJeff Kirsher * It both checks if the requested command is legal in a current 4908adfc5217SJeff Kirsher * state and, if it's legal, sets a `next_state' in the object 4909adfc5217SJeff Kirsher * that will be used in the completion flow to set the `state' 4910adfc5217SJeff Kirsher * of the object. 4911adfc5217SJeff Kirsher * 4912adfc5217SJeff Kirsher * returns 0 if a requested command is a legal transition, 4913adfc5217SJeff Kirsher * -EINVAL otherwise. 4914adfc5217SJeff Kirsher */ 4915adfc5217SJeff Kirsher static int bnx2x_queue_chk_transition(struct bnx2x *bp, 4916adfc5217SJeff Kirsher struct bnx2x_queue_sp_obj *o, 4917adfc5217SJeff Kirsher struct bnx2x_queue_state_params *params) 4918adfc5217SJeff Kirsher { 4919adfc5217SJeff Kirsher enum bnx2x_q_state state = o->state, next_state = BNX2X_Q_STATE_MAX; 4920adfc5217SJeff Kirsher enum bnx2x_queue_cmd cmd = params->cmd; 4921adfc5217SJeff Kirsher struct bnx2x_queue_update_params *update_params = 4922adfc5217SJeff Kirsher ¶ms->params.update; 4923adfc5217SJeff Kirsher u8 next_tx_only = o->num_tx_only; 4924adfc5217SJeff Kirsher 4925adfc5217SJeff Kirsher /* 4926adfc5217SJeff Kirsher * Forget all pending for completion commands if a driver only state 4927adfc5217SJeff Kirsher * transition has been requested. 4928adfc5217SJeff Kirsher */ 4929adfc5217SJeff Kirsher if (test_bit(RAMROD_DRV_CLR_ONLY, ¶ms->ramrod_flags)) { 4930adfc5217SJeff Kirsher o->pending = 0; 4931adfc5217SJeff Kirsher o->next_state = BNX2X_Q_STATE_MAX; 4932adfc5217SJeff Kirsher } 4933adfc5217SJeff Kirsher 4934adfc5217SJeff Kirsher /* 4935adfc5217SJeff Kirsher * Don't allow a next state transition if we are in the middle of 4936adfc5217SJeff Kirsher * the previous one. 4937adfc5217SJeff Kirsher */ 4938adfc5217SJeff Kirsher if (o->pending) 4939adfc5217SJeff Kirsher return -EBUSY; 4940adfc5217SJeff Kirsher 4941adfc5217SJeff Kirsher switch (state) { 4942adfc5217SJeff Kirsher case BNX2X_Q_STATE_RESET: 4943adfc5217SJeff Kirsher if (cmd == BNX2X_Q_CMD_INIT) 4944adfc5217SJeff Kirsher next_state = BNX2X_Q_STATE_INITIALIZED; 4945adfc5217SJeff Kirsher 4946adfc5217SJeff Kirsher break; 4947adfc5217SJeff Kirsher case BNX2X_Q_STATE_INITIALIZED: 4948adfc5217SJeff Kirsher if (cmd == BNX2X_Q_CMD_SETUP) { 4949adfc5217SJeff Kirsher if (test_bit(BNX2X_Q_FLG_ACTIVE, 4950adfc5217SJeff Kirsher ¶ms->params.setup.flags)) 4951adfc5217SJeff Kirsher next_state = BNX2X_Q_STATE_ACTIVE; 4952adfc5217SJeff Kirsher else 4953adfc5217SJeff Kirsher next_state = BNX2X_Q_STATE_INACTIVE; 4954adfc5217SJeff Kirsher } 4955adfc5217SJeff Kirsher 4956adfc5217SJeff Kirsher break; 4957adfc5217SJeff Kirsher case BNX2X_Q_STATE_ACTIVE: 4958adfc5217SJeff Kirsher if (cmd == BNX2X_Q_CMD_DEACTIVATE) 4959adfc5217SJeff Kirsher next_state = BNX2X_Q_STATE_INACTIVE; 4960adfc5217SJeff Kirsher 4961adfc5217SJeff Kirsher else if ((cmd == BNX2X_Q_CMD_EMPTY) || 4962adfc5217SJeff Kirsher (cmd == BNX2X_Q_CMD_UPDATE_TPA)) 4963adfc5217SJeff Kirsher next_state = BNX2X_Q_STATE_ACTIVE; 4964adfc5217SJeff Kirsher 4965adfc5217SJeff Kirsher else if (cmd == BNX2X_Q_CMD_SETUP_TX_ONLY) { 4966adfc5217SJeff Kirsher next_state = BNX2X_Q_STATE_MULTI_COS; 4967adfc5217SJeff Kirsher next_tx_only = 1; 4968adfc5217SJeff Kirsher } 4969adfc5217SJeff Kirsher 4970adfc5217SJeff Kirsher else if (cmd == BNX2X_Q_CMD_HALT) 4971adfc5217SJeff Kirsher next_state = BNX2X_Q_STATE_STOPPED; 4972adfc5217SJeff Kirsher 4973adfc5217SJeff Kirsher else if (cmd == BNX2X_Q_CMD_UPDATE) { 4974adfc5217SJeff Kirsher /* If "active" state change is requested, update the 4975adfc5217SJeff Kirsher * state accordingly. 4976adfc5217SJeff Kirsher */ 4977adfc5217SJeff Kirsher if (test_bit(BNX2X_Q_UPDATE_ACTIVATE_CHNG, 4978adfc5217SJeff Kirsher &update_params->update_flags) && 4979adfc5217SJeff Kirsher !test_bit(BNX2X_Q_UPDATE_ACTIVATE, 4980adfc5217SJeff Kirsher &update_params->update_flags)) 4981adfc5217SJeff Kirsher next_state = BNX2X_Q_STATE_INACTIVE; 4982adfc5217SJeff Kirsher else 4983adfc5217SJeff Kirsher next_state = BNX2X_Q_STATE_ACTIVE; 4984adfc5217SJeff Kirsher } 4985adfc5217SJeff Kirsher 4986adfc5217SJeff Kirsher break; 4987adfc5217SJeff Kirsher case BNX2X_Q_STATE_MULTI_COS: 4988adfc5217SJeff Kirsher if (cmd == BNX2X_Q_CMD_TERMINATE) 4989adfc5217SJeff Kirsher next_state = BNX2X_Q_STATE_MCOS_TERMINATED; 4990adfc5217SJeff Kirsher 4991adfc5217SJeff Kirsher else if (cmd == BNX2X_Q_CMD_SETUP_TX_ONLY) { 4992adfc5217SJeff Kirsher next_state = BNX2X_Q_STATE_MULTI_COS; 4993adfc5217SJeff Kirsher next_tx_only = o->num_tx_only + 1; 4994adfc5217SJeff Kirsher } 4995adfc5217SJeff Kirsher 4996adfc5217SJeff Kirsher else if ((cmd == BNX2X_Q_CMD_EMPTY) || 4997adfc5217SJeff Kirsher (cmd == BNX2X_Q_CMD_UPDATE_TPA)) 4998adfc5217SJeff Kirsher next_state = BNX2X_Q_STATE_MULTI_COS; 4999adfc5217SJeff Kirsher 5000adfc5217SJeff Kirsher else if (cmd == BNX2X_Q_CMD_UPDATE) { 5001adfc5217SJeff Kirsher /* If "active" state change is requested, update the 5002adfc5217SJeff Kirsher * state accordingly. 5003adfc5217SJeff Kirsher */ 5004adfc5217SJeff Kirsher if (test_bit(BNX2X_Q_UPDATE_ACTIVATE_CHNG, 5005adfc5217SJeff Kirsher &update_params->update_flags) && 5006adfc5217SJeff Kirsher !test_bit(BNX2X_Q_UPDATE_ACTIVATE, 5007adfc5217SJeff Kirsher &update_params->update_flags)) 5008adfc5217SJeff Kirsher next_state = BNX2X_Q_STATE_INACTIVE; 5009adfc5217SJeff Kirsher else 5010adfc5217SJeff Kirsher next_state = BNX2X_Q_STATE_MULTI_COS; 5011adfc5217SJeff Kirsher } 5012adfc5217SJeff Kirsher 5013adfc5217SJeff Kirsher break; 5014adfc5217SJeff Kirsher case BNX2X_Q_STATE_MCOS_TERMINATED: 5015adfc5217SJeff Kirsher if (cmd == BNX2X_Q_CMD_CFC_DEL) { 5016adfc5217SJeff Kirsher next_tx_only = o->num_tx_only - 1; 5017adfc5217SJeff Kirsher if (next_tx_only == 0) 5018adfc5217SJeff Kirsher next_state = BNX2X_Q_STATE_ACTIVE; 5019adfc5217SJeff Kirsher else 5020adfc5217SJeff Kirsher next_state = BNX2X_Q_STATE_MULTI_COS; 5021adfc5217SJeff Kirsher } 5022adfc5217SJeff Kirsher 5023adfc5217SJeff Kirsher break; 5024adfc5217SJeff Kirsher case BNX2X_Q_STATE_INACTIVE: 5025adfc5217SJeff Kirsher if (cmd == BNX2X_Q_CMD_ACTIVATE) 5026adfc5217SJeff Kirsher next_state = BNX2X_Q_STATE_ACTIVE; 5027adfc5217SJeff Kirsher 5028adfc5217SJeff Kirsher else if ((cmd == BNX2X_Q_CMD_EMPTY) || 5029adfc5217SJeff Kirsher (cmd == BNX2X_Q_CMD_UPDATE_TPA)) 5030adfc5217SJeff Kirsher next_state = BNX2X_Q_STATE_INACTIVE; 5031adfc5217SJeff Kirsher 5032adfc5217SJeff Kirsher else if (cmd == BNX2X_Q_CMD_HALT) 5033adfc5217SJeff Kirsher next_state = BNX2X_Q_STATE_STOPPED; 5034adfc5217SJeff Kirsher 5035adfc5217SJeff Kirsher else if (cmd == BNX2X_Q_CMD_UPDATE) { 5036adfc5217SJeff Kirsher /* If "active" state change is requested, update the 5037adfc5217SJeff Kirsher * state accordingly. 5038adfc5217SJeff Kirsher */ 5039adfc5217SJeff Kirsher if (test_bit(BNX2X_Q_UPDATE_ACTIVATE_CHNG, 5040adfc5217SJeff Kirsher &update_params->update_flags) && 5041adfc5217SJeff Kirsher test_bit(BNX2X_Q_UPDATE_ACTIVATE, 5042adfc5217SJeff Kirsher &update_params->update_flags)){ 5043adfc5217SJeff Kirsher if (o->num_tx_only == 0) 5044adfc5217SJeff Kirsher next_state = BNX2X_Q_STATE_ACTIVE; 5045adfc5217SJeff Kirsher else /* tx only queues exist for this queue */ 5046adfc5217SJeff Kirsher next_state = BNX2X_Q_STATE_MULTI_COS; 5047adfc5217SJeff Kirsher } else 5048adfc5217SJeff Kirsher next_state = BNX2X_Q_STATE_INACTIVE; 5049adfc5217SJeff Kirsher } 5050adfc5217SJeff Kirsher 5051adfc5217SJeff Kirsher break; 5052adfc5217SJeff Kirsher case BNX2X_Q_STATE_STOPPED: 5053adfc5217SJeff Kirsher if (cmd == BNX2X_Q_CMD_TERMINATE) 5054adfc5217SJeff Kirsher next_state = BNX2X_Q_STATE_TERMINATED; 5055adfc5217SJeff Kirsher 5056adfc5217SJeff Kirsher break; 5057adfc5217SJeff Kirsher case BNX2X_Q_STATE_TERMINATED: 5058adfc5217SJeff Kirsher if (cmd == BNX2X_Q_CMD_CFC_DEL) 5059adfc5217SJeff Kirsher next_state = BNX2X_Q_STATE_RESET; 5060adfc5217SJeff Kirsher 5061adfc5217SJeff Kirsher break; 5062adfc5217SJeff Kirsher default: 5063adfc5217SJeff Kirsher BNX2X_ERR("Illegal state: %d\n", state); 5064adfc5217SJeff Kirsher } 5065adfc5217SJeff Kirsher 5066adfc5217SJeff Kirsher /* Transition is assured */ 5067adfc5217SJeff Kirsher if (next_state != BNX2X_Q_STATE_MAX) { 5068adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "Good state transition: %d(%d)->%d\n", 5069adfc5217SJeff Kirsher state, cmd, next_state); 5070adfc5217SJeff Kirsher o->next_state = next_state; 5071adfc5217SJeff Kirsher o->next_tx_only = next_tx_only; 5072adfc5217SJeff Kirsher return 0; 5073adfc5217SJeff Kirsher } 5074adfc5217SJeff Kirsher 5075adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "Bad state transition request: %d %d\n", state, cmd); 5076adfc5217SJeff Kirsher 5077adfc5217SJeff Kirsher return -EINVAL; 5078adfc5217SJeff Kirsher } 5079adfc5217SJeff Kirsher 5080adfc5217SJeff Kirsher void bnx2x_init_queue_obj(struct bnx2x *bp, 5081adfc5217SJeff Kirsher struct bnx2x_queue_sp_obj *obj, 5082adfc5217SJeff Kirsher u8 cl_id, u32 *cids, u8 cid_cnt, u8 func_id, 5083adfc5217SJeff Kirsher void *rdata, 5084adfc5217SJeff Kirsher dma_addr_t rdata_mapping, unsigned long type) 5085adfc5217SJeff Kirsher { 5086adfc5217SJeff Kirsher memset(obj, 0, sizeof(*obj)); 5087adfc5217SJeff Kirsher 5088adfc5217SJeff Kirsher /* We support only BNX2X_MULTI_TX_COS Tx CoS at the moment */ 5089adfc5217SJeff Kirsher BUG_ON(BNX2X_MULTI_TX_COS < cid_cnt); 5090adfc5217SJeff Kirsher 5091adfc5217SJeff Kirsher memcpy(obj->cids, cids, sizeof(obj->cids[0]) * cid_cnt); 5092adfc5217SJeff Kirsher obj->max_cos = cid_cnt; 5093adfc5217SJeff Kirsher obj->cl_id = cl_id; 5094adfc5217SJeff Kirsher obj->func_id = func_id; 5095adfc5217SJeff Kirsher obj->rdata = rdata; 5096adfc5217SJeff Kirsher obj->rdata_mapping = rdata_mapping; 5097adfc5217SJeff Kirsher obj->type = type; 5098adfc5217SJeff Kirsher obj->next_state = BNX2X_Q_STATE_MAX; 5099adfc5217SJeff Kirsher 5100adfc5217SJeff Kirsher if (CHIP_IS_E1x(bp)) 5101adfc5217SJeff Kirsher obj->send_cmd = bnx2x_queue_send_cmd_e1x; 5102adfc5217SJeff Kirsher else 5103adfc5217SJeff Kirsher obj->send_cmd = bnx2x_queue_send_cmd_e2; 5104adfc5217SJeff Kirsher 5105adfc5217SJeff Kirsher obj->check_transition = bnx2x_queue_chk_transition; 5106adfc5217SJeff Kirsher 5107adfc5217SJeff Kirsher obj->complete_cmd = bnx2x_queue_comp_cmd; 5108adfc5217SJeff Kirsher obj->wait_comp = bnx2x_queue_wait_comp; 5109adfc5217SJeff Kirsher obj->set_pending = bnx2x_queue_set_pending; 5110adfc5217SJeff Kirsher } 5111adfc5217SJeff Kirsher 5112adfc5217SJeff Kirsher void bnx2x_queue_set_cos_cid(struct bnx2x *bp, 5113adfc5217SJeff Kirsher struct bnx2x_queue_sp_obj *obj, 5114adfc5217SJeff Kirsher u32 cid, u8 index) 5115adfc5217SJeff Kirsher { 5116adfc5217SJeff Kirsher obj->cids[index] = cid; 5117adfc5217SJeff Kirsher } 5118adfc5217SJeff Kirsher 5119adfc5217SJeff Kirsher /********************** Function state object *********************************/ 5120adfc5217SJeff Kirsher enum bnx2x_func_state bnx2x_func_get_state(struct bnx2x *bp, 5121adfc5217SJeff Kirsher struct bnx2x_func_sp_obj *o) 5122adfc5217SJeff Kirsher { 5123adfc5217SJeff Kirsher /* in the middle of transaction - return INVALID state */ 5124adfc5217SJeff Kirsher if (o->pending) 5125adfc5217SJeff Kirsher return BNX2X_F_STATE_MAX; 5126adfc5217SJeff Kirsher 5127adfc5217SJeff Kirsher /* 5128adfc5217SJeff Kirsher * unsure the order of reading of o->pending and o->state 5129adfc5217SJeff Kirsher * o->pending should be read first 5130adfc5217SJeff Kirsher */ 5131adfc5217SJeff Kirsher rmb(); 5132adfc5217SJeff Kirsher 5133adfc5217SJeff Kirsher return o->state; 5134adfc5217SJeff Kirsher } 5135adfc5217SJeff Kirsher 5136adfc5217SJeff Kirsher static int bnx2x_func_wait_comp(struct bnx2x *bp, 5137adfc5217SJeff Kirsher struct bnx2x_func_sp_obj *o, 5138adfc5217SJeff Kirsher enum bnx2x_func_cmd cmd) 5139adfc5217SJeff Kirsher { 5140adfc5217SJeff Kirsher return bnx2x_state_wait(bp, cmd, &o->pending); 5141adfc5217SJeff Kirsher } 5142adfc5217SJeff Kirsher 5143adfc5217SJeff Kirsher /** 5144adfc5217SJeff Kirsher * bnx2x_func_state_change_comp - complete the state machine transition 5145adfc5217SJeff Kirsher * 5146adfc5217SJeff Kirsher * @bp: device handle 5147adfc5217SJeff Kirsher * @o: 5148adfc5217SJeff Kirsher * @cmd: 5149adfc5217SJeff Kirsher * 5150adfc5217SJeff Kirsher * Called on state change transition. Completes the state 5151adfc5217SJeff Kirsher * machine transition only - no HW interaction. 5152adfc5217SJeff Kirsher */ 5153adfc5217SJeff Kirsher static inline int bnx2x_func_state_change_comp(struct bnx2x *bp, 5154adfc5217SJeff Kirsher struct bnx2x_func_sp_obj *o, 5155adfc5217SJeff Kirsher enum bnx2x_func_cmd cmd) 5156adfc5217SJeff Kirsher { 5157adfc5217SJeff Kirsher unsigned long cur_pending = o->pending; 5158adfc5217SJeff Kirsher 5159adfc5217SJeff Kirsher if (!test_and_clear_bit(cmd, &cur_pending)) { 5160adfc5217SJeff Kirsher BNX2X_ERR("Bad MC reply %d for func %d in state %d " 5161adfc5217SJeff Kirsher "pending 0x%lx, next_state %d\n", cmd, BP_FUNC(bp), 5162adfc5217SJeff Kirsher o->state, cur_pending, o->next_state); 5163adfc5217SJeff Kirsher return -EINVAL; 5164adfc5217SJeff Kirsher } 5165adfc5217SJeff Kirsher 516694f05b0fSJoe Perches DP(BNX2X_MSG_SP, 516794f05b0fSJoe Perches "Completing command %d for func %d, setting state to %d\n", 516894f05b0fSJoe Perches cmd, BP_FUNC(bp), o->next_state); 5169adfc5217SJeff Kirsher 5170adfc5217SJeff Kirsher o->state = o->next_state; 5171adfc5217SJeff Kirsher o->next_state = BNX2X_F_STATE_MAX; 5172adfc5217SJeff Kirsher 5173adfc5217SJeff Kirsher /* It's important that o->state and o->next_state are 5174adfc5217SJeff Kirsher * updated before o->pending. 5175adfc5217SJeff Kirsher */ 5176adfc5217SJeff Kirsher wmb(); 5177adfc5217SJeff Kirsher 5178adfc5217SJeff Kirsher clear_bit(cmd, &o->pending); 5179adfc5217SJeff Kirsher smp_mb__after_clear_bit(); 5180adfc5217SJeff Kirsher 5181adfc5217SJeff Kirsher return 0; 5182adfc5217SJeff Kirsher } 5183adfc5217SJeff Kirsher 5184adfc5217SJeff Kirsher /** 5185adfc5217SJeff Kirsher * bnx2x_func_comp_cmd - complete the state change command 5186adfc5217SJeff Kirsher * 5187adfc5217SJeff Kirsher * @bp: device handle 5188adfc5217SJeff Kirsher * @o: 5189adfc5217SJeff Kirsher * @cmd: 5190adfc5217SJeff Kirsher * 5191adfc5217SJeff Kirsher * Checks that the arrived completion is expected. 5192adfc5217SJeff Kirsher */ 5193adfc5217SJeff Kirsher static int bnx2x_func_comp_cmd(struct bnx2x *bp, 5194adfc5217SJeff Kirsher struct bnx2x_func_sp_obj *o, 5195adfc5217SJeff Kirsher enum bnx2x_func_cmd cmd) 5196adfc5217SJeff Kirsher { 5197adfc5217SJeff Kirsher /* Complete the state machine part first, check if it's a 5198adfc5217SJeff Kirsher * legal completion. 5199adfc5217SJeff Kirsher */ 5200adfc5217SJeff Kirsher int rc = bnx2x_func_state_change_comp(bp, o, cmd); 5201adfc5217SJeff Kirsher return rc; 5202adfc5217SJeff Kirsher } 5203adfc5217SJeff Kirsher 5204adfc5217SJeff Kirsher /** 5205adfc5217SJeff Kirsher * bnx2x_func_chk_transition - perform function state machine transition 5206adfc5217SJeff Kirsher * 5207adfc5217SJeff Kirsher * @bp: device handle 5208adfc5217SJeff Kirsher * @o: 5209adfc5217SJeff Kirsher * @params: 5210adfc5217SJeff Kirsher * 5211adfc5217SJeff Kirsher * It both checks if the requested command is legal in a current 5212adfc5217SJeff Kirsher * state and, if it's legal, sets a `next_state' in the object 5213adfc5217SJeff Kirsher * that will be used in the completion flow to set the `state' 5214adfc5217SJeff Kirsher * of the object. 5215adfc5217SJeff Kirsher * 5216adfc5217SJeff Kirsher * returns 0 if a requested command is a legal transition, 5217adfc5217SJeff Kirsher * -EINVAL otherwise. 5218adfc5217SJeff Kirsher */ 5219adfc5217SJeff Kirsher static int bnx2x_func_chk_transition(struct bnx2x *bp, 5220adfc5217SJeff Kirsher struct bnx2x_func_sp_obj *o, 5221adfc5217SJeff Kirsher struct bnx2x_func_state_params *params) 5222adfc5217SJeff Kirsher { 5223adfc5217SJeff Kirsher enum bnx2x_func_state state = o->state, next_state = BNX2X_F_STATE_MAX; 5224adfc5217SJeff Kirsher enum bnx2x_func_cmd cmd = params->cmd; 5225adfc5217SJeff Kirsher 5226adfc5217SJeff Kirsher /* 5227adfc5217SJeff Kirsher * Forget all pending for completion commands if a driver only state 5228adfc5217SJeff Kirsher * transition has been requested. 5229adfc5217SJeff Kirsher */ 5230adfc5217SJeff Kirsher if (test_bit(RAMROD_DRV_CLR_ONLY, ¶ms->ramrod_flags)) { 5231adfc5217SJeff Kirsher o->pending = 0; 5232adfc5217SJeff Kirsher o->next_state = BNX2X_F_STATE_MAX; 5233adfc5217SJeff Kirsher } 5234adfc5217SJeff Kirsher 5235adfc5217SJeff Kirsher /* 5236adfc5217SJeff Kirsher * Don't allow a next state transition if we are in the middle of 5237adfc5217SJeff Kirsher * the previous one. 5238adfc5217SJeff Kirsher */ 5239adfc5217SJeff Kirsher if (o->pending) 5240adfc5217SJeff Kirsher return -EBUSY; 5241adfc5217SJeff Kirsher 5242adfc5217SJeff Kirsher switch (state) { 5243adfc5217SJeff Kirsher case BNX2X_F_STATE_RESET: 5244adfc5217SJeff Kirsher if (cmd == BNX2X_F_CMD_HW_INIT) 5245adfc5217SJeff Kirsher next_state = BNX2X_F_STATE_INITIALIZED; 5246adfc5217SJeff Kirsher 5247adfc5217SJeff Kirsher break; 5248adfc5217SJeff Kirsher case BNX2X_F_STATE_INITIALIZED: 5249adfc5217SJeff Kirsher if (cmd == BNX2X_F_CMD_START) 5250adfc5217SJeff Kirsher next_state = BNX2X_F_STATE_STARTED; 5251adfc5217SJeff Kirsher 5252adfc5217SJeff Kirsher else if (cmd == BNX2X_F_CMD_HW_RESET) 5253adfc5217SJeff Kirsher next_state = BNX2X_F_STATE_RESET; 5254adfc5217SJeff Kirsher 5255adfc5217SJeff Kirsher break; 5256adfc5217SJeff Kirsher case BNX2X_F_STATE_STARTED: 5257adfc5217SJeff Kirsher if (cmd == BNX2X_F_CMD_STOP) 5258adfc5217SJeff Kirsher next_state = BNX2X_F_STATE_INITIALIZED; 5259adfc5217SJeff Kirsher else if (cmd == BNX2X_F_CMD_TX_STOP) 5260adfc5217SJeff Kirsher next_state = BNX2X_F_STATE_TX_STOPPED; 5261adfc5217SJeff Kirsher 5262adfc5217SJeff Kirsher break; 5263adfc5217SJeff Kirsher case BNX2X_F_STATE_TX_STOPPED: 5264adfc5217SJeff Kirsher if (cmd == BNX2X_F_CMD_TX_START) 5265adfc5217SJeff Kirsher next_state = BNX2X_F_STATE_STARTED; 5266adfc5217SJeff Kirsher 5267adfc5217SJeff Kirsher break; 5268adfc5217SJeff Kirsher default: 5269adfc5217SJeff Kirsher BNX2X_ERR("Unknown state: %d\n", state); 5270adfc5217SJeff Kirsher } 5271adfc5217SJeff Kirsher 5272adfc5217SJeff Kirsher /* Transition is assured */ 5273adfc5217SJeff Kirsher if (next_state != BNX2X_F_STATE_MAX) { 5274adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "Good function state transition: %d(%d)->%d\n", 5275adfc5217SJeff Kirsher state, cmd, next_state); 5276adfc5217SJeff Kirsher o->next_state = next_state; 5277adfc5217SJeff Kirsher return 0; 5278adfc5217SJeff Kirsher } 5279adfc5217SJeff Kirsher 5280adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "Bad function state transition request: %d %d\n", 5281adfc5217SJeff Kirsher state, cmd); 5282adfc5217SJeff Kirsher 5283adfc5217SJeff Kirsher return -EINVAL; 5284adfc5217SJeff Kirsher } 5285adfc5217SJeff Kirsher 5286adfc5217SJeff Kirsher /** 5287adfc5217SJeff Kirsher * bnx2x_func_init_func - performs HW init at function stage 5288adfc5217SJeff Kirsher * 5289adfc5217SJeff Kirsher * @bp: device handle 5290adfc5217SJeff Kirsher * @drv: 5291adfc5217SJeff Kirsher * 5292adfc5217SJeff Kirsher * Init HW when the current phase is 5293adfc5217SJeff Kirsher * FW_MSG_CODE_DRV_LOAD_FUNCTION: initialize only FUNCTION-only 5294adfc5217SJeff Kirsher * HW blocks. 5295adfc5217SJeff Kirsher */ 5296adfc5217SJeff Kirsher static inline int bnx2x_func_init_func(struct bnx2x *bp, 5297adfc5217SJeff Kirsher const struct bnx2x_func_sp_drv_ops *drv) 5298adfc5217SJeff Kirsher { 5299adfc5217SJeff Kirsher return drv->init_hw_func(bp); 5300adfc5217SJeff Kirsher } 5301adfc5217SJeff Kirsher 5302adfc5217SJeff Kirsher /** 5303adfc5217SJeff Kirsher * bnx2x_func_init_port - performs HW init at port stage 5304adfc5217SJeff Kirsher * 5305adfc5217SJeff Kirsher * @bp: device handle 5306adfc5217SJeff Kirsher * @drv: 5307adfc5217SJeff Kirsher * 5308adfc5217SJeff Kirsher * Init HW when the current phase is 5309adfc5217SJeff Kirsher * FW_MSG_CODE_DRV_LOAD_PORT: initialize PORT-only and 5310adfc5217SJeff Kirsher * FUNCTION-only HW blocks. 5311adfc5217SJeff Kirsher * 5312adfc5217SJeff Kirsher */ 5313adfc5217SJeff Kirsher static inline int bnx2x_func_init_port(struct bnx2x *bp, 5314adfc5217SJeff Kirsher const struct bnx2x_func_sp_drv_ops *drv) 5315adfc5217SJeff Kirsher { 5316adfc5217SJeff Kirsher int rc = drv->init_hw_port(bp); 5317adfc5217SJeff Kirsher if (rc) 5318adfc5217SJeff Kirsher return rc; 5319adfc5217SJeff Kirsher 5320adfc5217SJeff Kirsher return bnx2x_func_init_func(bp, drv); 5321adfc5217SJeff Kirsher } 5322adfc5217SJeff Kirsher 5323adfc5217SJeff Kirsher /** 5324adfc5217SJeff Kirsher * bnx2x_func_init_cmn_chip - performs HW init at chip-common stage 5325adfc5217SJeff Kirsher * 5326adfc5217SJeff Kirsher * @bp: device handle 5327adfc5217SJeff Kirsher * @drv: 5328adfc5217SJeff Kirsher * 5329adfc5217SJeff Kirsher * Init HW when the current phase is 5330adfc5217SJeff Kirsher * FW_MSG_CODE_DRV_LOAD_COMMON_CHIP: initialize COMMON_CHIP, 5331adfc5217SJeff Kirsher * PORT-only and FUNCTION-only HW blocks. 5332adfc5217SJeff Kirsher */ 5333adfc5217SJeff Kirsher static inline int bnx2x_func_init_cmn_chip(struct bnx2x *bp, 5334adfc5217SJeff Kirsher const struct bnx2x_func_sp_drv_ops *drv) 5335adfc5217SJeff Kirsher { 5336adfc5217SJeff Kirsher int rc = drv->init_hw_cmn_chip(bp); 5337adfc5217SJeff Kirsher if (rc) 5338adfc5217SJeff Kirsher return rc; 5339adfc5217SJeff Kirsher 5340adfc5217SJeff Kirsher return bnx2x_func_init_port(bp, drv); 5341adfc5217SJeff Kirsher } 5342adfc5217SJeff Kirsher 5343adfc5217SJeff Kirsher /** 5344adfc5217SJeff Kirsher * bnx2x_func_init_cmn - performs HW init at common stage 5345adfc5217SJeff Kirsher * 5346adfc5217SJeff Kirsher * @bp: device handle 5347adfc5217SJeff Kirsher * @drv: 5348adfc5217SJeff Kirsher * 5349adfc5217SJeff Kirsher * Init HW when the current phase is 5350adfc5217SJeff Kirsher * FW_MSG_CODE_DRV_LOAD_COMMON_CHIP: initialize COMMON, 5351adfc5217SJeff Kirsher * PORT-only and FUNCTION-only HW blocks. 5352adfc5217SJeff Kirsher */ 5353adfc5217SJeff Kirsher static inline int bnx2x_func_init_cmn(struct bnx2x *bp, 5354adfc5217SJeff Kirsher const struct bnx2x_func_sp_drv_ops *drv) 5355adfc5217SJeff Kirsher { 5356adfc5217SJeff Kirsher int rc = drv->init_hw_cmn(bp); 5357adfc5217SJeff Kirsher if (rc) 5358adfc5217SJeff Kirsher return rc; 5359adfc5217SJeff Kirsher 5360adfc5217SJeff Kirsher return bnx2x_func_init_port(bp, drv); 5361adfc5217SJeff Kirsher } 5362adfc5217SJeff Kirsher 5363adfc5217SJeff Kirsher static int bnx2x_func_hw_init(struct bnx2x *bp, 5364adfc5217SJeff Kirsher struct bnx2x_func_state_params *params) 5365adfc5217SJeff Kirsher { 5366adfc5217SJeff Kirsher u32 load_code = params->params.hw_init.load_phase; 5367adfc5217SJeff Kirsher struct bnx2x_func_sp_obj *o = params->f_obj; 5368adfc5217SJeff Kirsher const struct bnx2x_func_sp_drv_ops *drv = o->drv; 5369adfc5217SJeff Kirsher int rc = 0; 5370adfc5217SJeff Kirsher 5371adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "function %d load_code %x\n", 5372adfc5217SJeff Kirsher BP_ABS_FUNC(bp), load_code); 5373adfc5217SJeff Kirsher 5374adfc5217SJeff Kirsher /* Prepare buffers for unzipping the FW */ 5375adfc5217SJeff Kirsher rc = drv->gunzip_init(bp); 5376adfc5217SJeff Kirsher if (rc) 5377adfc5217SJeff Kirsher return rc; 5378adfc5217SJeff Kirsher 5379adfc5217SJeff Kirsher /* Prepare FW */ 5380adfc5217SJeff Kirsher rc = drv->init_fw(bp); 5381adfc5217SJeff Kirsher if (rc) { 5382adfc5217SJeff Kirsher BNX2X_ERR("Error loading firmware\n"); 5383eb2afd4aSDmitry Kravkov goto init_err; 5384adfc5217SJeff Kirsher } 5385adfc5217SJeff Kirsher 5386adfc5217SJeff Kirsher /* Handle the beginning of COMMON_XXX pases separatelly... */ 5387adfc5217SJeff Kirsher switch (load_code) { 5388adfc5217SJeff Kirsher case FW_MSG_CODE_DRV_LOAD_COMMON_CHIP: 5389adfc5217SJeff Kirsher rc = bnx2x_func_init_cmn_chip(bp, drv); 5390adfc5217SJeff Kirsher if (rc) 5391eb2afd4aSDmitry Kravkov goto init_err; 5392adfc5217SJeff Kirsher 5393adfc5217SJeff Kirsher break; 5394adfc5217SJeff Kirsher case FW_MSG_CODE_DRV_LOAD_COMMON: 5395adfc5217SJeff Kirsher rc = bnx2x_func_init_cmn(bp, drv); 5396adfc5217SJeff Kirsher if (rc) 5397eb2afd4aSDmitry Kravkov goto init_err; 5398adfc5217SJeff Kirsher 5399adfc5217SJeff Kirsher break; 5400adfc5217SJeff Kirsher case FW_MSG_CODE_DRV_LOAD_PORT: 5401adfc5217SJeff Kirsher rc = bnx2x_func_init_port(bp, drv); 5402adfc5217SJeff Kirsher if (rc) 5403eb2afd4aSDmitry Kravkov goto init_err; 5404adfc5217SJeff Kirsher 5405adfc5217SJeff Kirsher break; 5406adfc5217SJeff Kirsher case FW_MSG_CODE_DRV_LOAD_FUNCTION: 5407adfc5217SJeff Kirsher rc = bnx2x_func_init_func(bp, drv); 5408adfc5217SJeff Kirsher if (rc) 5409eb2afd4aSDmitry Kravkov goto init_err; 5410adfc5217SJeff Kirsher 5411adfc5217SJeff Kirsher break; 5412adfc5217SJeff Kirsher default: 5413adfc5217SJeff Kirsher BNX2X_ERR("Unknown load_code (0x%x) from MCP\n", load_code); 5414adfc5217SJeff Kirsher rc = -EINVAL; 5415adfc5217SJeff Kirsher } 5416adfc5217SJeff Kirsher 5417eb2afd4aSDmitry Kravkov init_err: 5418adfc5217SJeff Kirsher drv->gunzip_end(bp); 5419adfc5217SJeff Kirsher 5420adfc5217SJeff Kirsher /* In case of success, complete the comand immediatelly: no ramrods 5421adfc5217SJeff Kirsher * have been sent. 5422adfc5217SJeff Kirsher */ 5423adfc5217SJeff Kirsher if (!rc) 5424adfc5217SJeff Kirsher o->complete_cmd(bp, o, BNX2X_F_CMD_HW_INIT); 5425adfc5217SJeff Kirsher 5426adfc5217SJeff Kirsher return rc; 5427adfc5217SJeff Kirsher } 5428adfc5217SJeff Kirsher 5429adfc5217SJeff Kirsher /** 5430adfc5217SJeff Kirsher * bnx2x_func_reset_func - reset HW at function stage 5431adfc5217SJeff Kirsher * 5432adfc5217SJeff Kirsher * @bp: device handle 5433adfc5217SJeff Kirsher * @drv: 5434adfc5217SJeff Kirsher * 5435adfc5217SJeff Kirsher * Reset HW at FW_MSG_CODE_DRV_UNLOAD_FUNCTION stage: reset only 5436adfc5217SJeff Kirsher * FUNCTION-only HW blocks. 5437adfc5217SJeff Kirsher */ 5438adfc5217SJeff Kirsher static inline void bnx2x_func_reset_func(struct bnx2x *bp, 5439adfc5217SJeff Kirsher const struct bnx2x_func_sp_drv_ops *drv) 5440adfc5217SJeff Kirsher { 5441adfc5217SJeff Kirsher drv->reset_hw_func(bp); 5442adfc5217SJeff Kirsher } 5443adfc5217SJeff Kirsher 5444adfc5217SJeff Kirsher /** 5445adfc5217SJeff Kirsher * bnx2x_func_reset_port - reser HW at port stage 5446adfc5217SJeff Kirsher * 5447adfc5217SJeff Kirsher * @bp: device handle 5448adfc5217SJeff Kirsher * @drv: 5449adfc5217SJeff Kirsher * 5450adfc5217SJeff Kirsher * Reset HW at FW_MSG_CODE_DRV_UNLOAD_PORT stage: reset 5451adfc5217SJeff Kirsher * FUNCTION-only and PORT-only HW blocks. 5452adfc5217SJeff Kirsher * 5453adfc5217SJeff Kirsher * !!!IMPORTANT!!! 5454adfc5217SJeff Kirsher * 5455adfc5217SJeff Kirsher * It's important to call reset_port before reset_func() as the last thing 5456adfc5217SJeff Kirsher * reset_func does is pf_disable() thus disabling PGLUE_B, which 5457adfc5217SJeff Kirsher * makes impossible any DMAE transactions. 5458adfc5217SJeff Kirsher */ 5459adfc5217SJeff Kirsher static inline void bnx2x_func_reset_port(struct bnx2x *bp, 5460adfc5217SJeff Kirsher const struct bnx2x_func_sp_drv_ops *drv) 5461adfc5217SJeff Kirsher { 5462adfc5217SJeff Kirsher drv->reset_hw_port(bp); 5463adfc5217SJeff Kirsher bnx2x_func_reset_func(bp, drv); 5464adfc5217SJeff Kirsher } 5465adfc5217SJeff Kirsher 5466adfc5217SJeff Kirsher /** 5467adfc5217SJeff Kirsher * bnx2x_func_reset_cmn - reser HW at common stage 5468adfc5217SJeff Kirsher * 5469adfc5217SJeff Kirsher * @bp: device handle 5470adfc5217SJeff Kirsher * @drv: 5471adfc5217SJeff Kirsher * 5472adfc5217SJeff Kirsher * Reset HW at FW_MSG_CODE_DRV_UNLOAD_COMMON and 5473adfc5217SJeff Kirsher * FW_MSG_CODE_DRV_UNLOAD_COMMON_CHIP stages: reset COMMON, 5474adfc5217SJeff Kirsher * COMMON_CHIP, FUNCTION-only and PORT-only HW blocks. 5475adfc5217SJeff Kirsher */ 5476adfc5217SJeff Kirsher static inline void bnx2x_func_reset_cmn(struct bnx2x *bp, 5477adfc5217SJeff Kirsher const struct bnx2x_func_sp_drv_ops *drv) 5478adfc5217SJeff Kirsher { 5479adfc5217SJeff Kirsher bnx2x_func_reset_port(bp, drv); 5480adfc5217SJeff Kirsher drv->reset_hw_cmn(bp); 5481adfc5217SJeff Kirsher } 5482adfc5217SJeff Kirsher 5483adfc5217SJeff Kirsher 5484adfc5217SJeff Kirsher static inline int bnx2x_func_hw_reset(struct bnx2x *bp, 5485adfc5217SJeff Kirsher struct bnx2x_func_state_params *params) 5486adfc5217SJeff Kirsher { 5487adfc5217SJeff Kirsher u32 reset_phase = params->params.hw_reset.reset_phase; 5488adfc5217SJeff Kirsher struct bnx2x_func_sp_obj *o = params->f_obj; 5489adfc5217SJeff Kirsher const struct bnx2x_func_sp_drv_ops *drv = o->drv; 5490adfc5217SJeff Kirsher 5491adfc5217SJeff Kirsher DP(BNX2X_MSG_SP, "function %d reset_phase %x\n", BP_ABS_FUNC(bp), 5492adfc5217SJeff Kirsher reset_phase); 5493adfc5217SJeff Kirsher 5494adfc5217SJeff Kirsher switch (reset_phase) { 5495adfc5217SJeff Kirsher case FW_MSG_CODE_DRV_UNLOAD_COMMON: 5496adfc5217SJeff Kirsher bnx2x_func_reset_cmn(bp, drv); 5497adfc5217SJeff Kirsher break; 5498adfc5217SJeff Kirsher case FW_MSG_CODE_DRV_UNLOAD_PORT: 5499adfc5217SJeff Kirsher bnx2x_func_reset_port(bp, drv); 5500adfc5217SJeff Kirsher break; 5501adfc5217SJeff Kirsher case FW_MSG_CODE_DRV_UNLOAD_FUNCTION: 5502adfc5217SJeff Kirsher bnx2x_func_reset_func(bp, drv); 5503adfc5217SJeff Kirsher break; 5504adfc5217SJeff Kirsher default: 5505adfc5217SJeff Kirsher BNX2X_ERR("Unknown reset_phase (0x%x) from MCP\n", 5506adfc5217SJeff Kirsher reset_phase); 5507adfc5217SJeff Kirsher break; 5508adfc5217SJeff Kirsher } 5509adfc5217SJeff Kirsher 5510adfc5217SJeff Kirsher /* Complete the comand immediatelly: no ramrods have been sent. */ 5511adfc5217SJeff Kirsher o->complete_cmd(bp, o, BNX2X_F_CMD_HW_RESET); 5512adfc5217SJeff Kirsher 5513adfc5217SJeff Kirsher return 0; 5514adfc5217SJeff Kirsher } 5515adfc5217SJeff Kirsher 5516adfc5217SJeff Kirsher static inline int bnx2x_func_send_start(struct bnx2x *bp, 5517adfc5217SJeff Kirsher struct bnx2x_func_state_params *params) 5518adfc5217SJeff Kirsher { 5519adfc5217SJeff Kirsher struct bnx2x_func_sp_obj *o = params->f_obj; 5520adfc5217SJeff Kirsher struct function_start_data *rdata = 5521adfc5217SJeff Kirsher (struct function_start_data *)o->rdata; 5522adfc5217SJeff Kirsher dma_addr_t data_mapping = o->rdata_mapping; 5523adfc5217SJeff Kirsher struct bnx2x_func_start_params *start_params = ¶ms->params.start; 5524adfc5217SJeff Kirsher 5525adfc5217SJeff Kirsher memset(rdata, 0, sizeof(*rdata)); 5526adfc5217SJeff Kirsher 5527adfc5217SJeff Kirsher /* Fill the ramrod data with provided parameters */ 5528adfc5217SJeff Kirsher rdata->function_mode = cpu_to_le16(start_params->mf_mode); 5529adfc5217SJeff Kirsher rdata->sd_vlan_tag = start_params->sd_vlan_tag; 5530adfc5217SJeff Kirsher rdata->path_id = BP_PATH(bp); 5531adfc5217SJeff Kirsher rdata->network_cos_mode = start_params->network_cos_mode; 5532adfc5217SJeff Kirsher 5533adfc5217SJeff Kirsher /* 5534adfc5217SJeff Kirsher * No need for an explicit memory barrier here as long we would 5535adfc5217SJeff Kirsher * need to ensure the ordering of writing to the SPQ element 5536adfc5217SJeff Kirsher * and updating of the SPQ producer which involves a memory 5537adfc5217SJeff Kirsher * read and we will have to put a full memory barrier there 5538adfc5217SJeff Kirsher * (inside bnx2x_sp_post()). 5539adfc5217SJeff Kirsher */ 5540adfc5217SJeff Kirsher 5541adfc5217SJeff Kirsher return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_FUNCTION_START, 0, 5542adfc5217SJeff Kirsher U64_HI(data_mapping), 5543adfc5217SJeff Kirsher U64_LO(data_mapping), NONE_CONNECTION_TYPE); 5544adfc5217SJeff Kirsher } 5545adfc5217SJeff Kirsher 5546adfc5217SJeff Kirsher static inline int bnx2x_func_send_stop(struct bnx2x *bp, 5547adfc5217SJeff Kirsher struct bnx2x_func_state_params *params) 5548adfc5217SJeff Kirsher { 5549adfc5217SJeff Kirsher return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_FUNCTION_STOP, 0, 0, 0, 5550adfc5217SJeff Kirsher NONE_CONNECTION_TYPE); 5551adfc5217SJeff Kirsher } 5552adfc5217SJeff Kirsher 5553adfc5217SJeff Kirsher static inline int bnx2x_func_send_tx_stop(struct bnx2x *bp, 5554adfc5217SJeff Kirsher struct bnx2x_func_state_params *params) 5555adfc5217SJeff Kirsher { 5556adfc5217SJeff Kirsher return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_STOP_TRAFFIC, 0, 0, 0, 5557adfc5217SJeff Kirsher NONE_CONNECTION_TYPE); 5558adfc5217SJeff Kirsher } 5559adfc5217SJeff Kirsher static inline int bnx2x_func_send_tx_start(struct bnx2x *bp, 5560adfc5217SJeff Kirsher struct bnx2x_func_state_params *params) 5561adfc5217SJeff Kirsher { 5562adfc5217SJeff Kirsher struct bnx2x_func_sp_obj *o = params->f_obj; 5563adfc5217SJeff Kirsher struct flow_control_configuration *rdata = 5564adfc5217SJeff Kirsher (struct flow_control_configuration *)o->rdata; 5565adfc5217SJeff Kirsher dma_addr_t data_mapping = o->rdata_mapping; 5566adfc5217SJeff Kirsher struct bnx2x_func_tx_start_params *tx_start_params = 5567adfc5217SJeff Kirsher ¶ms->params.tx_start; 5568adfc5217SJeff Kirsher int i; 5569adfc5217SJeff Kirsher 5570adfc5217SJeff Kirsher memset(rdata, 0, sizeof(*rdata)); 5571adfc5217SJeff Kirsher 5572adfc5217SJeff Kirsher rdata->dcb_enabled = tx_start_params->dcb_enabled; 5573adfc5217SJeff Kirsher rdata->dcb_version = tx_start_params->dcb_version; 5574adfc5217SJeff Kirsher rdata->dont_add_pri_0_en = tx_start_params->dont_add_pri_0_en; 5575adfc5217SJeff Kirsher 5576adfc5217SJeff Kirsher for (i = 0; i < ARRAY_SIZE(rdata->traffic_type_to_priority_cos); i++) 5577adfc5217SJeff Kirsher rdata->traffic_type_to_priority_cos[i] = 5578adfc5217SJeff Kirsher tx_start_params->traffic_type_to_priority_cos[i]; 5579adfc5217SJeff Kirsher 5580adfc5217SJeff Kirsher return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_START_TRAFFIC, 0, 5581adfc5217SJeff Kirsher U64_HI(data_mapping), 5582adfc5217SJeff Kirsher U64_LO(data_mapping), NONE_CONNECTION_TYPE); 5583adfc5217SJeff Kirsher } 5584adfc5217SJeff Kirsher 5585adfc5217SJeff Kirsher static int bnx2x_func_send_cmd(struct bnx2x *bp, 5586adfc5217SJeff Kirsher struct bnx2x_func_state_params *params) 5587adfc5217SJeff Kirsher { 5588adfc5217SJeff Kirsher switch (params->cmd) { 5589adfc5217SJeff Kirsher case BNX2X_F_CMD_HW_INIT: 5590adfc5217SJeff Kirsher return bnx2x_func_hw_init(bp, params); 5591adfc5217SJeff Kirsher case BNX2X_F_CMD_START: 5592adfc5217SJeff Kirsher return bnx2x_func_send_start(bp, params); 5593adfc5217SJeff Kirsher case BNX2X_F_CMD_STOP: 5594adfc5217SJeff Kirsher return bnx2x_func_send_stop(bp, params); 5595adfc5217SJeff Kirsher case BNX2X_F_CMD_HW_RESET: 5596adfc5217SJeff Kirsher return bnx2x_func_hw_reset(bp, params); 5597adfc5217SJeff Kirsher case BNX2X_F_CMD_TX_STOP: 5598adfc5217SJeff Kirsher return bnx2x_func_send_tx_stop(bp, params); 5599adfc5217SJeff Kirsher case BNX2X_F_CMD_TX_START: 5600adfc5217SJeff Kirsher return bnx2x_func_send_tx_start(bp, params); 5601adfc5217SJeff Kirsher default: 5602adfc5217SJeff Kirsher BNX2X_ERR("Unknown command: %d\n", params->cmd); 5603adfc5217SJeff Kirsher return -EINVAL; 5604adfc5217SJeff Kirsher } 5605adfc5217SJeff Kirsher } 5606adfc5217SJeff Kirsher 5607adfc5217SJeff Kirsher void bnx2x_init_func_obj(struct bnx2x *bp, 5608adfc5217SJeff Kirsher struct bnx2x_func_sp_obj *obj, 5609adfc5217SJeff Kirsher void *rdata, dma_addr_t rdata_mapping, 5610adfc5217SJeff Kirsher struct bnx2x_func_sp_drv_ops *drv_iface) 5611adfc5217SJeff Kirsher { 5612adfc5217SJeff Kirsher memset(obj, 0, sizeof(*obj)); 5613adfc5217SJeff Kirsher 5614adfc5217SJeff Kirsher mutex_init(&obj->one_pending_mutex); 5615adfc5217SJeff Kirsher 5616adfc5217SJeff Kirsher obj->rdata = rdata; 5617adfc5217SJeff Kirsher obj->rdata_mapping = rdata_mapping; 5618adfc5217SJeff Kirsher 5619adfc5217SJeff Kirsher obj->send_cmd = bnx2x_func_send_cmd; 5620adfc5217SJeff Kirsher obj->check_transition = bnx2x_func_chk_transition; 5621adfc5217SJeff Kirsher obj->complete_cmd = bnx2x_func_comp_cmd; 5622adfc5217SJeff Kirsher obj->wait_comp = bnx2x_func_wait_comp; 5623adfc5217SJeff Kirsher 5624adfc5217SJeff Kirsher obj->drv = drv_iface; 5625adfc5217SJeff Kirsher } 5626adfc5217SJeff Kirsher 5627adfc5217SJeff Kirsher /** 5628adfc5217SJeff Kirsher * bnx2x_func_state_change - perform Function state change transition 5629adfc5217SJeff Kirsher * 5630adfc5217SJeff Kirsher * @bp: device handle 5631adfc5217SJeff Kirsher * @params: parameters to perform the transaction 5632adfc5217SJeff Kirsher * 5633adfc5217SJeff Kirsher * returns 0 in case of successfully completed transition, 5634adfc5217SJeff Kirsher * negative error code in case of failure, positive 5635adfc5217SJeff Kirsher * (EBUSY) value if there is a completion to that is 5636adfc5217SJeff Kirsher * still pending (possible only if RAMROD_COMP_WAIT is 5637adfc5217SJeff Kirsher * not set in params->ramrod_flags for asynchronous 5638adfc5217SJeff Kirsher * commands). 5639adfc5217SJeff Kirsher */ 5640adfc5217SJeff Kirsher int bnx2x_func_state_change(struct bnx2x *bp, 5641adfc5217SJeff Kirsher struct bnx2x_func_state_params *params) 5642adfc5217SJeff Kirsher { 5643adfc5217SJeff Kirsher struct bnx2x_func_sp_obj *o = params->f_obj; 5644adfc5217SJeff Kirsher int rc; 5645adfc5217SJeff Kirsher enum bnx2x_func_cmd cmd = params->cmd; 5646adfc5217SJeff Kirsher unsigned long *pending = &o->pending; 5647adfc5217SJeff Kirsher 5648adfc5217SJeff Kirsher mutex_lock(&o->one_pending_mutex); 5649adfc5217SJeff Kirsher 5650adfc5217SJeff Kirsher /* Check that the requested transition is legal */ 5651adfc5217SJeff Kirsher if (o->check_transition(bp, o, params)) { 5652adfc5217SJeff Kirsher mutex_unlock(&o->one_pending_mutex); 5653adfc5217SJeff Kirsher return -EINVAL; 5654adfc5217SJeff Kirsher } 5655adfc5217SJeff Kirsher 5656adfc5217SJeff Kirsher /* Set "pending" bit */ 5657adfc5217SJeff Kirsher set_bit(cmd, pending); 5658adfc5217SJeff Kirsher 5659adfc5217SJeff Kirsher /* Don't send a command if only driver cleanup was requested */ 5660adfc5217SJeff Kirsher if (test_bit(RAMROD_DRV_CLR_ONLY, ¶ms->ramrod_flags)) { 5661adfc5217SJeff Kirsher bnx2x_func_state_change_comp(bp, o, cmd); 5662adfc5217SJeff Kirsher mutex_unlock(&o->one_pending_mutex); 5663adfc5217SJeff Kirsher } else { 5664adfc5217SJeff Kirsher /* Send a ramrod */ 5665adfc5217SJeff Kirsher rc = o->send_cmd(bp, params); 5666adfc5217SJeff Kirsher 5667adfc5217SJeff Kirsher mutex_unlock(&o->one_pending_mutex); 5668adfc5217SJeff Kirsher 5669adfc5217SJeff Kirsher if (rc) { 5670adfc5217SJeff Kirsher o->next_state = BNX2X_F_STATE_MAX; 5671adfc5217SJeff Kirsher clear_bit(cmd, pending); 5672adfc5217SJeff Kirsher smp_mb__after_clear_bit(); 5673adfc5217SJeff Kirsher return rc; 5674adfc5217SJeff Kirsher } 5675adfc5217SJeff Kirsher 5676adfc5217SJeff Kirsher if (test_bit(RAMROD_COMP_WAIT, ¶ms->ramrod_flags)) { 5677adfc5217SJeff Kirsher rc = o->wait_comp(bp, o, cmd); 5678adfc5217SJeff Kirsher if (rc) 5679adfc5217SJeff Kirsher return rc; 5680adfc5217SJeff Kirsher 5681adfc5217SJeff Kirsher return 0; 5682adfc5217SJeff Kirsher } 5683adfc5217SJeff Kirsher } 5684adfc5217SJeff Kirsher 5685adfc5217SJeff Kirsher return !!test_bit(cmd, pending); 5686adfc5217SJeff Kirsher } 5687