Hi all, Today's linux-next merge of the net-next tree got a conflict in drivers/net/ethernet/emulex/benet/be.h between commit e9e2a904ef0a ("be2net: Warn users of possible broken functionality on BE2 cards with very old FW versions with latest driver") from the net tree and commit 6384a4d0dcf9 ("be2net: add support for ndo_busy_poll") from the net-next tree. I fixed it up (see below) and can carry the fix as necessary (no action is required). -- Cheers, Stephen Rothwell sfr@canb.auug.org.au diff --cc drivers/net/ethernet/emulex/benet/be.h index c99dac6a9ddf,b2765ebb0268..000000000000 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h @@@ -696,23 -733,114 +733,123 @@@ static inline int qnq_async_evt_rcvd(st return adapter->flags & BE_FLAGS_QNQ_ASYNC_EVT_RCVD; } +static inline int fw_major_num(const char *fw_ver) +{ + int fw_major = 0; + + sscanf(fw_ver, "%d.", &fw_major); + + return fw_major; +} + - extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, - u16 num_popped); - extern void be_link_status_update(struct be_adapter *adapter, u8 link_status); - extern void be_parse_stats(struct be_adapter *adapter); - extern int be_load_fw(struct be_adapter *adapter, u8 *func); - extern bool be_is_wol_supported(struct be_adapter *adapter); - extern bool be_pause_supported(struct be_adapter *adapter); - extern u32 be_get_fw_log_level(struct be_adapter *adapter); + #ifdef CONFIG_NET_RX_BUSY_POLL + static inline bool be_lock_napi(struct be_eq_obj *eqo) + { + bool status = true; + + spin_lock(&eqo->lock); /* BH is already disabled */ + if (eqo->state & BE_EQ_LOCKED) { + WARN_ON(eqo->state & BE_EQ_NAPI); + eqo->state |= BE_EQ_NAPI_YIELD; + status = false; + } else { + eqo->state = BE_EQ_NAPI; + } + spin_unlock(&eqo->lock); + return status; + } + + static inline void be_unlock_napi(struct be_eq_obj *eqo) + { + spin_lock(&eqo->lock); /* BH is already disabled */ + + WARN_ON(eqo->state & (BE_EQ_POLL | BE_EQ_NAPI_YIELD)); + eqo->state = BE_EQ_IDLE; + + spin_unlock(&eqo->lock); + } + + static inline bool be_lock_busy_poll(struct be_eq_obj *eqo) + { + bool status = true; + + spin_lock_bh(&eqo->lock); + if (eqo->state & BE_EQ_LOCKED) { + eqo->state |= BE_EQ_POLL_YIELD; + status = false; + } else { + eqo->state |= BE_EQ_POLL; + } + spin_unlock_bh(&eqo->lock); + return status; + } + + static inline void be_unlock_busy_poll(struct be_eq_obj *eqo) + { + spin_lock_bh(&eqo->lock); + + WARN_ON(eqo->state & (BE_EQ_NAPI)); + eqo->state = BE_EQ_IDLE; + + spin_unlock_bh(&eqo->lock); + } + + static inline void be_enable_busy_poll(struct be_eq_obj *eqo) + { + spin_lock_init(&eqo->lock); + eqo->state = BE_EQ_IDLE; + } + + static inline void be_disable_busy_poll(struct be_eq_obj *eqo) + { + local_bh_disable(); + + /* It's enough to just acquire napi lock on the eqo to stop + * be_busy_poll() from processing any queueus. + */ + while (!be_lock_napi(eqo)) + mdelay(1); + + local_bh_enable(); + } + + #else /* CONFIG_NET_RX_BUSY_POLL */ + + static inline bool be_lock_napi(struct be_eq_obj *eqo) + { + return true; + } + + static inline void be_unlock_napi(struct be_eq_obj *eqo) + { + } + + static inline bool be_lock_busy_poll(struct be_eq_obj *eqo) + { + return false; + } + + static inline void be_unlock_busy_poll(struct be_eq_obj *eqo) + { + } + + static inline void be_enable_busy_poll(struct be_eq_obj *eqo) + { + } + + static inline void be_disable_busy_poll(struct be_eq_obj *eqo) + { + } + #endif /* CONFIG_NET_RX_BUSY_POLL */ + + void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, + u16 num_popped); + void be_link_status_update(struct be_adapter *adapter, u8 link_status); + void be_parse_stats(struct be_adapter *adapter); + int be_load_fw(struct be_adapter *adapter, u8 *func); + bool be_is_wol_supported(struct be_adapter *adapter); + bool be_pause_supported(struct be_adapter *adapter); + u32 be_get_fw_log_level(struct be_adapter *adapter); int be_update_queues(struct be_adapter *adapter); int be_poll(struct napi_struct *napi, int budget);