~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to drivers/net/sfc/mcdi.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno
  • Date: 2011-06-07 12:14:05 UTC
  • mfrom: (43.1.9 sid)
  • Revision ID: james.westby@ubuntu.com-20110607121405-i3h1rd7nrnd2b73h
Tags: 2.6.39-2
[ Ben Hutchings ]
* [x86] Enable BACKLIGHT_APPLE, replacing BACKLIGHT_MBP_NVIDIA
  (Closes: #627492)
* cgroups: Disable memory resource controller by default. Allow it
  to be enabled using kernel parameter 'cgroup_enable=memory'.
* rt2800usb: Enable support for more USB devices including
  Linksys WUSB600N (Closes: #596626) (this change was accidentally
  omitted from 2.6.39-1)
* [x86] Remove Celeron from list of processors supporting PAE. Most
  'Celeron M' models do not.
* Update debconf template translations:
  - Swedish (Martin Bagge) (Closes: #628932)
  - French (David Prévot) (Closes: #628191)
* aufs: Update for 2.6.39 (Closes: #627837)
* Add stable 2.6.39.1, including:
  - ext4: dont set PageUptodate in ext4_end_bio()
  - pata_cmd64x: fix boot crash on parisc (Closes: #622997, #622745)
  - ext3: Fix fs corruption when make_indexed_dir() fails
  - netfilter: nf_ct_sip: validate Content-Length in TCP SIP messages
  - sctp: fix race between sctp_bind_addr_free() and
    sctp_bind_addr_conflict()
  - sctp: fix memory leak of the ASCONF queue when free asoc
  - md/bitmap: fix saving of events_cleared and other state
  - cdc_acm: Fix oops when Droids MuIn LCD is connected
  - cx88: Fix conversion from BKL to fine-grained locks (Closes: #619827)
  - keys: Set cred->user_ns in key_replace_session_keyring (CVE-2011-2184)
  - tmpfs: fix race between truncate and writepage
  - nfs41: Correct offset for LAYOUTCOMMIT
  - xen/mmu: fix a race window causing leave_mm BUG()
  - ext4: fix possible use-after-free in ext4_remove_li_request()
  For the complete list of changes, see:
   http://www.kernel.org/pub/linux/kernel/v2.6/ChangeLog-2.6.39.1
* Bump ABI to 2
* netfilter: Enable IP_SET, IP_SET_BITMAP_IP, IP_SET_BITMAP_IPMAC,
  IP_SET_BITMAP_PORT, IP_SET_HASH_IP, IP_SET_HASH_IPPORT,
  IP_SET_HASH_IPPORTIP, IP_SET_HASH_IPPORTNET, IP_SET_HASH_NET,
  IP_SET_HASH_NETPORT, IP_SET_LIST_SET, NETFILTER_XT_SET as modules
  (Closes: #629401)

[ Aurelien Jarno ]
* [mipsel/loongson-2f] Disable_SCSI_LPFC to workaround GCC ICE.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/****************************************************************************
2
2
 * Driver for Solarflare Solarstorm network controllers and boards
3
 
 * Copyright 2008-2009 Solarflare Communications Inc.
 
3
 * Copyright 2008-2011 Solarflare Communications Inc.
4
4
 *
5
5
 * This program is free software; you can redistribute it and/or modify it
6
6
 * under the terms of the GNU General Public License version 2 as published
50
50
        return &nic_data->mcdi;
51
51
}
52
52
 
 
53
static inline void
 
54
efx_mcdi_readd(struct efx_nic *efx, efx_dword_t *value, unsigned reg)
 
55
{
 
56
        struct siena_nic_data *nic_data = efx->nic_data;
 
57
        value->u32[0] = (__force __le32)__raw_readl(nic_data->mcdi_smem + reg);
 
58
}
 
59
 
 
60
static inline void
 
61
efx_mcdi_writed(struct efx_nic *efx, const efx_dword_t *value, unsigned reg)
 
62
{
 
63
        struct siena_nic_data *nic_data = efx->nic_data;
 
64
        __raw_writel((__force u32)value->u32[0], nic_data->mcdi_smem + reg);
 
65
}
 
66
 
53
67
void efx_mcdi_init(struct efx_nic *efx)
54
68
{
55
69
        struct efx_mcdi_iface *mcdi;
70
84
                            const u8 *inbuf, size_t inlen)
71
85
{
72
86
        struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
73
 
        unsigned pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx);
74
 
        unsigned doorbell = FR_CZ_MC_TREG_SMEM + MCDI_DOORBELL(efx);
 
87
        unsigned pdu = MCDI_PDU(efx);
 
88
        unsigned doorbell = MCDI_DOORBELL(efx);
75
89
        unsigned int i;
76
90
        efx_dword_t hdr;
77
91
        u32 xflags, seqno;
92
106
                             MCDI_HEADER_SEQ, seqno,
93
107
                             MCDI_HEADER_XFLAGS, xflags);
94
108
 
95
 
        efx_writed(efx, &hdr, pdu);
 
109
        efx_mcdi_writed(efx, &hdr, pdu);
96
110
 
97
111
        for (i = 0; i < inlen; i += 4)
98
 
                _efx_writed(efx, *((__le32 *)(inbuf + i)), pdu + 4 + i);
99
 
 
100
 
        /* Ensure the payload is written out before the header */
101
 
        wmb();
 
112
                efx_mcdi_writed(efx, (const efx_dword_t *)(inbuf + i),
 
113
                                pdu + 4 + i);
102
114
 
103
115
        /* ring the doorbell with a distinctive value */
104
 
        _efx_writed(efx, (__force __le32) 0x45789abc, doorbell);
 
116
        EFX_POPULATE_DWORD_1(hdr, EFX_DWORD_0, 0x45789abc);
 
117
        efx_mcdi_writed(efx, &hdr, doorbell);
105
118
}
106
119
 
107
120
static void efx_mcdi_copyout(struct efx_nic *efx, u8 *outbuf, size_t outlen)
108
121
{
109
122
        struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
110
 
        unsigned int pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx);
 
123
        unsigned int pdu = MCDI_PDU(efx);
111
124
        int i;
112
125
 
113
126
        BUG_ON(atomic_read(&mcdi->state) == MCDI_STATE_QUIESCENT);
114
127
        BUG_ON(outlen & 3 || outlen >= 0x100);
115
128
 
116
129
        for (i = 0; i < outlen; i += 4)
117
 
                *((__le32 *)(outbuf + i)) = _efx_readd(efx, pdu + 4 + i);
 
130
                efx_mcdi_readd(efx, (efx_dword_t *)(outbuf + i), pdu + 4 + i);
118
131
}
119
132
 
120
133
static int efx_mcdi_poll(struct efx_nic *efx)
122
135
        struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
123
136
        unsigned int time, finish;
124
137
        unsigned int respseq, respcmd, error;
125
 
        unsigned int pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx);
 
138
        unsigned int pdu = MCDI_PDU(efx);
126
139
        unsigned int rc, spins;
127
140
        efx_dword_t reg;
128
141
 
148
161
 
149
162
                time = get_seconds();
150
163
 
151
 
                rmb();
152
 
                efx_readd(efx, &reg, pdu);
 
164
                efx_mcdi_readd(efx, &reg, pdu);
153
165
 
154
166
                /* All 1's indicates that shared memory is in reset (and is
155
167
                 * not a valid header). Wait for it to come out reset before
176
188
                          respseq, mcdi->seqno);
177
189
                rc = EIO;
178
190
        } else if (error) {
179
 
                efx_readd(efx, &reg, pdu + 4);
 
191
                efx_mcdi_readd(efx, &reg, pdu + 4);
180
192
                switch (EFX_DWORD_FIELD(reg, EFX_DWORD_0)) {
181
193
#define TRANSLATE_ERROR(name)                                   \
182
194
                case MC_CMD_ERR_ ## name:                       \
210
222
/* Test and clear MC-rebooted flag for this port/function */
211
223
int efx_mcdi_poll_reboot(struct efx_nic *efx)
212
224
{
213
 
        unsigned int addr = FR_CZ_MC_TREG_SMEM + MCDI_REBOOT_FLAG(efx);
 
225
        unsigned int addr = MCDI_REBOOT_FLAG(efx);
214
226
        efx_dword_t reg;
215
227
        uint32_t value;
216
228
 
217
229
        if (efx_nic_rev(efx) < EFX_REV_SIENA_A0)
218
230
                return false;
219
231
 
220
 
        efx_readd(efx, &reg, addr);
 
232
        efx_mcdi_readd(efx, &reg, addr);
221
233
        value = EFX_DWORD_FIELD(reg, EFX_DWORD_0);
222
234
 
223
235
        if (value == 0)
224
236
                return 0;
225
237
 
226
238
        EFX_ZERO_DWORD(reg);
227
 
        efx_writed(efx, &reg, addr);
 
239
        efx_mcdi_writed(efx, &reg, addr);
228
240
 
229
241
        if (value == MC_STATUS_DWORD_ASSERT)
230
242
                return -EINTR;
452
464
         *
453
465
         * There's a race here with efx_mcdi_rpc(), because we might receive
454
466
         * a REBOOT event *before* the request has been copied out. In polled
455
 
         * mode (during startup) this is irrelevent, because efx_mcdi_complete()
 
467
         * mode (during startup) this is irrelevant, because efx_mcdi_complete()
456
468
         * is ignored. In event mode, this condition is just an edge-case of
457
469
         * receiving a REBOOT event after posting the MCDI request. Did the mc
458
470
         * reboot before or after the copyout? The best we can do always is
602
614
 **************************************************************************
603
615
 */
604
616
 
605
 
int efx_mcdi_fwver(struct efx_nic *efx, u64 *version, u32 *build)
 
617
void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len)
606
618
{
607
619
        u8 outbuf[ALIGN(MC_CMD_GET_VERSION_V1_OUT_LEN, 4)];
608
620
        size_t outlength;
616
628
        if (rc)
617
629
                goto fail;
618
630
 
619
 
        if (outlength == MC_CMD_GET_VERSION_V0_OUT_LEN) {
620
 
                *version = 0;
621
 
                *build = MCDI_DWORD(outbuf, GET_VERSION_OUT_FIRMWARE);
622
 
                return 0;
623
 
        }
624
 
 
625
631
        if (outlength < MC_CMD_GET_VERSION_V1_OUT_LEN) {
626
632
                rc = -EIO;
627
633
                goto fail;
628
634
        }
629
635
 
630
636
        ver_words = (__le16 *)MCDI_PTR(outbuf, GET_VERSION_OUT_VERSION);
631
 
        *version = (((u64)le16_to_cpu(ver_words[0]) << 48) |
632
 
                    ((u64)le16_to_cpu(ver_words[1]) << 32) |
633
 
                    ((u64)le16_to_cpu(ver_words[2]) << 16) |
634
 
                    le16_to_cpu(ver_words[3]));
635
 
        *build = MCDI_DWORD(outbuf, GET_VERSION_OUT_FIRMWARE);
636
 
 
637
 
        return 0;
 
637
        snprintf(buf, len, "%u.%u.%u.%u",
 
638
                 le16_to_cpu(ver_words[0]), le16_to_cpu(ver_words[1]),
 
639
                 le16_to_cpu(ver_words[2]), le16_to_cpu(ver_words[3]));
 
640
        return;
638
641
 
639
642
fail:
640
643
        netif_err(efx, probe, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
641
 
        return rc;
 
644
        buf[0] = 0;
642
645
}
643
646
 
644
647
int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating,