long timeout;
        unsigned char *data;
        void (*finalize)(struct qeth_card *card, struct qeth_cmd_buffer *iob);
+       bool (*match)(struct qeth_cmd_buffer *iob,
+                     struct qeth_cmd_buffer *reply);
        void (*callback)(struct qeth_card *card, struct qeth_cmd_buffer *iob,
                         unsigned int data_length);
        int rc;
        refcount_inc(&iob->ref_count);
 }
 
+static inline struct qeth_ipa_cmd *__ipa_reply(struct qeth_cmd_buffer *iob)
+{
+       if (!IS_IPA(iob->data))
+               return NULL;
+
+       return (struct qeth_ipa_cmd *) PDU_ENCAPSULATION(iob->data);
+}
+
 static inline struct qeth_ipa_cmd *__ipa_cmd(struct qeth_cmd_buffer *iob)
 {
        return (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE);
 int qeth_setadpparms_change_macaddr(struct qeth_card *);
 void qeth_tx_timeout(struct net_device *, unsigned int txqueue);
 void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
-                         u16 cmd_length);
+                         u16 cmd_length,
+                         bool (*match)(struct qeth_cmd_buffer *iob,
+                                       struct qeth_cmd_buffer *reply));
 int qeth_query_switch_attributes(struct qeth_card *card,
                                  struct qeth_switch_info *sw_info);
 int qeth_query_card_info(struct qeth_card *card,
 
                goto out;
        }
 
-       if (IS_IPA(iob->data)) {
-               cmd = (struct qeth_ipa_cmd *) PDU_ENCAPSULATION(iob->data);
+       cmd = __ipa_reply(iob);
+       if (cmd) {
                cmd = qeth_check_ipa_data(card, cmd);
                if (!cmd)
                        goto out;
                        card->osn_info.assist_cb(card->dev, cmd);
                        goto out;
                }
-       } else {
-               /* non-IPA commands should only flow during initialization */
-               if (card->state != CARD_STATE_DOWN)
-                       goto out;
        }
 
        /* match against pending cmd requests */
        spin_lock_irqsave(&card->lock, flags);
        list_for_each_entry(tmp, &card->cmd_waiter_list, list) {
-               if (!IS_IPA(tmp->data) ||
-                   __ipa_cmd(tmp)->hdr.seqno == cmd->hdr.seqno) {
+               if (tmp->match && tmp->match(tmp, iob)) {
                        request = tmp;
                        /* take the object outside the lock */
                        qeth_get_cmd(request);
        iob->callback = qeth_release_buffer_cb;
 }
 
+static bool qeth_mpc_match_reply(struct qeth_cmd_buffer *iob,
+                                struct qeth_cmd_buffer *reply)
+{
+       /* MPC cmds are issued strictly in sequence. */
+       return !IS_IPA(reply->data);
+}
+
 static struct qeth_cmd_buffer *qeth_mpc_alloc_cmd(struct qeth_card *card,
                                                  void *data,
                                                  unsigned int data_length)
        qeth_setup_ccw(__ccw_from_cmd(iob), CCW_CMD_WRITE, 0, data_length,
                       iob->data);
        iob->finalize = qeth_mpc_finalize_cmd;
+       iob->match = qeth_mpc_match_reply;
        return iob;
 }
 
 }
 
 void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
-                         u16 cmd_length)
+                         u16 cmd_length,
+                         bool (*match)(struct qeth_cmd_buffer *iob,
+                                       struct qeth_cmd_buffer *reply))
 {
        u8 prot_type = qeth_mpc_select_prot_type(card);
        u16 total_length = iob->length;
        qeth_setup_ccw(__ccw_from_cmd(iob), CCW_CMD_WRITE, 0, total_length,
                       iob->data);
        iob->finalize = qeth_ipa_finalize_cmd;
+       iob->match = match;
 
        memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);
        memcpy(QETH_IPA_PDU_LEN_TOTAL(iob->data), &total_length, 2);
 }
 EXPORT_SYMBOL_GPL(qeth_prepare_ipa_cmd);
 
+static bool qeth_ipa_match_reply(struct qeth_cmd_buffer *iob,
+                                struct qeth_cmd_buffer *reply)
+{
+       struct qeth_ipa_cmd *ipa_reply = __ipa_reply(reply);
+
+       return ipa_reply && (__ipa_cmd(iob)->hdr.seqno == ipa_reply->hdr.seqno);
+}
+
 struct qeth_cmd_buffer *qeth_ipa_alloc_cmd(struct qeth_card *card,
                                           enum qeth_ipa_cmds cmd_code,
                                           enum qeth_prot_versions prot,
        if (!iob)
                return NULL;
 
-       qeth_prepare_ipa_cmd(card, iob, data_length);
+       qeth_prepare_ipa_cmd(card, iob, data_length, qeth_ipa_match_reply);
 
        hdr = &__ipa_cmd(iob)->hdr;
        hdr->command = cmd_code;