diff options
author | David S. Miller <davem@davemloft.net> | 2011-05-17 17:33:11 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-05-17 17:33:11 -0400 |
commit | 9cbc94eabb0791906051bbfac024ef2c2be8e079 (patch) | |
tree | 41ba194e687c6c60f5c883f98737ac83257d0c00 /drivers/net/sfc | |
parent | 1d1652cbdb9885e4d73972263e4cdbe1b0beebfe (diff) | |
parent | 7cc31a9ae1477abc79d5992b3afe889f25c50c99 (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts:
drivers/net/vmxnet3/vmxnet3_ethtool.c
net/core/dev.c
Diffstat (limited to 'drivers/net/sfc')
-rw-r--r-- | drivers/net/sfc/mcdi.c | 49 | ||||
-rw-r--r-- | drivers/net/sfc/nic.c | 7 | ||||
-rw-r--r-- | drivers/net/sfc/nic.h | 2 | ||||
-rw-r--r-- | drivers/net/sfc/siena.c | 25 |
4 files changed, 60 insertions, 23 deletions
diff --git a/drivers/net/sfc/mcdi.c b/drivers/net/sfc/mcdi.c index d98479030ef2..3dd45ed61f0a 100644 --- a/drivers/net/sfc/mcdi.c +++ b/drivers/net/sfc/mcdi.c | |||
@@ -50,6 +50,20 @@ static inline struct efx_mcdi_iface *efx_mcdi(struct efx_nic *efx) | |||
50 | return &nic_data->mcdi; | 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 | void efx_mcdi_init(struct efx_nic *efx) | 67 | void efx_mcdi_init(struct efx_nic *efx) |
54 | { | 68 | { |
55 | struct efx_mcdi_iface *mcdi; | 69 | struct efx_mcdi_iface *mcdi; |
@@ -70,8 +84,8 @@ static void efx_mcdi_copyin(struct efx_nic *efx, unsigned cmd, | |||
70 | const u8 *inbuf, size_t inlen) | 84 | const u8 *inbuf, size_t inlen) |
71 | { | 85 | { |
72 | struct efx_mcdi_iface *mcdi = efx_mcdi(efx); | 86 | struct efx_mcdi_iface *mcdi = efx_mcdi(efx); |
73 | unsigned pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx); | 87 | unsigned pdu = MCDI_PDU(efx); |
74 | unsigned doorbell = FR_CZ_MC_TREG_SMEM + MCDI_DOORBELL(efx); | 88 | unsigned doorbell = MCDI_DOORBELL(efx); |
75 | unsigned int i; | 89 | unsigned int i; |
76 | efx_dword_t hdr; | 90 | efx_dword_t hdr; |
77 | u32 xflags, seqno; | 91 | u32 xflags, seqno; |
@@ -92,30 +106,28 @@ static void efx_mcdi_copyin(struct efx_nic *efx, unsigned cmd, | |||
92 | MCDI_HEADER_SEQ, seqno, | 106 | MCDI_HEADER_SEQ, seqno, |
93 | MCDI_HEADER_XFLAGS, xflags); | 107 | MCDI_HEADER_XFLAGS, xflags); |
94 | 108 | ||
95 | efx_writed(efx, &hdr, pdu); | 109 | efx_mcdi_writed(efx, &hdr, pdu); |
96 | 110 | ||
97 | for (i = 0; i < inlen; i += 4) { | 111 | for (i = 0; i < inlen; i += 4) |
98 | _efx_writed(efx, *((__le32 *)(inbuf + i)), pdu + 4 + i); | 112 | efx_mcdi_writed(efx, (const efx_dword_t *)(inbuf + i), |
99 | /* use wmb() within loop to inhibit write combining */ | 113 | pdu + 4 + i); |
100 | wmb(); | ||
101 | } | ||
102 | 114 | ||
103 | /* ring the doorbell with a distinctive value */ | 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); |
105 | wmb(); | 117 | efx_mcdi_writed(efx, &hdr, doorbell); |
106 | } | 118 | } |
107 | 119 | ||
108 | static void efx_mcdi_copyout(struct efx_nic *efx, u8 *outbuf, size_t outlen) | 120 | static void efx_mcdi_copyout(struct efx_nic *efx, u8 *outbuf, size_t outlen) |
109 | { | 121 | { |
110 | struct efx_mcdi_iface *mcdi = efx_mcdi(efx); | 122 | struct efx_mcdi_iface *mcdi = efx_mcdi(efx); |
111 | unsigned int pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx); | 123 | unsigned int pdu = MCDI_PDU(efx); |
112 | int i; | 124 | int i; |
113 | 125 | ||
114 | BUG_ON(atomic_read(&mcdi->state) == MCDI_STATE_QUIESCENT); | 126 | BUG_ON(atomic_read(&mcdi->state) == MCDI_STATE_QUIESCENT); |
115 | BUG_ON(outlen & 3 || outlen >= 0x100); | 127 | BUG_ON(outlen & 3 || outlen >= 0x100); |
116 | 128 | ||
117 | for (i = 0; i < outlen; i += 4) | 129 | for (i = 0; i < outlen; i += 4) |
118 | *((__le32 *)(outbuf + i)) = _efx_readd(efx, pdu + 4 + i); | 130 | efx_mcdi_readd(efx, (efx_dword_t *)(outbuf + i), pdu + 4 + i); |
119 | } | 131 | } |
120 | 132 | ||
121 | static int efx_mcdi_poll(struct efx_nic *efx) | 133 | static int efx_mcdi_poll(struct efx_nic *efx) |
@@ -123,7 +135,7 @@ static int efx_mcdi_poll(struct efx_nic *efx) | |||
123 | struct efx_mcdi_iface *mcdi = efx_mcdi(efx); | 135 | struct efx_mcdi_iface *mcdi = efx_mcdi(efx); |
124 | unsigned int time, finish; | 136 | unsigned int time, finish; |
125 | unsigned int respseq, respcmd, error; | 137 | unsigned int respseq, respcmd, error; |
126 | unsigned int pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx); | 138 | unsigned int pdu = MCDI_PDU(efx); |
127 | unsigned int rc, spins; | 139 | unsigned int rc, spins; |
128 | efx_dword_t reg; | 140 | efx_dword_t reg; |
129 | 141 | ||
@@ -149,8 +161,7 @@ static int efx_mcdi_poll(struct efx_nic *efx) | |||
149 | 161 | ||
150 | time = get_seconds(); | 162 | time = get_seconds(); |
151 | 163 | ||
152 | rmb(); | 164 | efx_mcdi_readd(efx, ®, pdu); |
153 | efx_readd(efx, ®, pdu); | ||
154 | 165 | ||
155 | /* All 1's indicates that shared memory is in reset (and is | 166 | /* All 1's indicates that shared memory is in reset (and is |
156 | * not a valid header). Wait for it to come out reset before | 167 | * not a valid header). Wait for it to come out reset before |
@@ -177,7 +188,7 @@ static int efx_mcdi_poll(struct efx_nic *efx) | |||
177 | respseq, mcdi->seqno); | 188 | respseq, mcdi->seqno); |
178 | rc = EIO; | 189 | rc = EIO; |
179 | } else if (error) { | 190 | } else if (error) { |
180 | efx_readd(efx, ®, pdu + 4); | 191 | efx_mcdi_readd(efx, ®, pdu + 4); |
181 | switch (EFX_DWORD_FIELD(reg, EFX_DWORD_0)) { | 192 | switch (EFX_DWORD_FIELD(reg, EFX_DWORD_0)) { |
182 | #define TRANSLATE_ERROR(name) \ | 193 | #define TRANSLATE_ERROR(name) \ |
183 | case MC_CMD_ERR_ ## name: \ | 194 | case MC_CMD_ERR_ ## name: \ |
@@ -211,21 +222,21 @@ out: | |||
211 | /* Test and clear MC-rebooted flag for this port/function */ | 222 | /* Test and clear MC-rebooted flag for this port/function */ |
212 | int efx_mcdi_poll_reboot(struct efx_nic *efx) | 223 | int efx_mcdi_poll_reboot(struct efx_nic *efx) |
213 | { | 224 | { |
214 | unsigned int addr = FR_CZ_MC_TREG_SMEM + MCDI_REBOOT_FLAG(efx); | 225 | unsigned int addr = MCDI_REBOOT_FLAG(efx); |
215 | efx_dword_t reg; | 226 | efx_dword_t reg; |
216 | uint32_t value; | 227 | uint32_t value; |
217 | 228 | ||
218 | if (efx_nic_rev(efx) < EFX_REV_SIENA_A0) | 229 | if (efx_nic_rev(efx) < EFX_REV_SIENA_A0) |
219 | return false; | 230 | return false; |
220 | 231 | ||
221 | efx_readd(efx, ®, addr); | 232 | efx_mcdi_readd(efx, ®, addr); |
222 | value = EFX_DWORD_FIELD(reg, EFX_DWORD_0); | 233 | value = EFX_DWORD_FIELD(reg, EFX_DWORD_0); |
223 | 234 | ||
224 | if (value == 0) | 235 | if (value == 0) |
225 | return 0; | 236 | return 0; |
226 | 237 | ||
227 | EFX_ZERO_DWORD(reg); | 238 | EFX_ZERO_DWORD(reg); |
228 | efx_writed(efx, ®, addr); | 239 | efx_mcdi_writed(efx, ®, addr); |
229 | 240 | ||
230 | if (value == MC_STATUS_DWORD_ASSERT) | 241 | if (value == MC_STATUS_DWORD_ASSERT) |
231 | return -EINTR; | 242 | return -EINTR; |
diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index 5ac9fa2cd3bc..f2a2b947f860 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c | |||
@@ -1935,6 +1935,13 @@ void efx_nic_get_regs(struct efx_nic *efx, void *buf) | |||
1935 | 1935 | ||
1936 | size = min_t(size_t, table->step, 16); | 1936 | size = min_t(size_t, table->step, 16); |
1937 | 1937 | ||
1938 | if (table->offset >= efx->type->mem_map_size) { | ||
1939 | /* No longer mapped; return dummy data */ | ||
1940 | memcpy(buf, "\xde\xc0\xad\xde", 4); | ||
1941 | buf += table->rows * size; | ||
1942 | continue; | ||
1943 | } | ||
1944 | |||
1938 | for (i = 0; i < table->rows; i++) { | 1945 | for (i = 0; i < table->rows; i++) { |
1939 | switch (table->step) { | 1946 | switch (table->step) { |
1940 | case 4: /* 32-bit register or SRAM */ | 1947 | case 4: /* 32-bit register or SRAM */ |
diff --git a/drivers/net/sfc/nic.h b/drivers/net/sfc/nic.h index 7443f99c977f..4bd1f2839dfe 100644 --- a/drivers/net/sfc/nic.h +++ b/drivers/net/sfc/nic.h | |||
@@ -143,10 +143,12 @@ static inline struct falcon_board *falcon_board(struct efx_nic *efx) | |||
143 | /** | 143 | /** |
144 | * struct siena_nic_data - Siena NIC state | 144 | * struct siena_nic_data - Siena NIC state |
145 | * @mcdi: Management-Controller-to-Driver Interface | 145 | * @mcdi: Management-Controller-to-Driver Interface |
146 | * @mcdi_smem: MCDI shared memory mapping. The mapping is always uncacheable. | ||
146 | * @wol_filter_id: Wake-on-LAN packet filter id | 147 | * @wol_filter_id: Wake-on-LAN packet filter id |
147 | */ | 148 | */ |
148 | struct siena_nic_data { | 149 | struct siena_nic_data { |
149 | struct efx_mcdi_iface mcdi; | 150 | struct efx_mcdi_iface mcdi; |
151 | void __iomem *mcdi_smem; | ||
150 | int wol_filter_id; | 152 | int wol_filter_id; |
151 | }; | 153 | }; |
152 | 154 | ||
diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c index ceac1c9907f0..fb4721f780ff 100644 --- a/drivers/net/sfc/siena.c +++ b/drivers/net/sfc/siena.c | |||
@@ -220,12 +220,26 @@ static int siena_probe_nic(struct efx_nic *efx) | |||
220 | efx_reado(efx, ®, FR_AZ_CS_DEBUG); | 220 | efx_reado(efx, ®, FR_AZ_CS_DEBUG); |
221 | efx->net_dev->dev_id = EFX_OWORD_FIELD(reg, FRF_CZ_CS_PORT_NUM) - 1; | 221 | efx->net_dev->dev_id = EFX_OWORD_FIELD(reg, FRF_CZ_CS_PORT_NUM) - 1; |
222 | 222 | ||
223 | /* Initialise MCDI */ | ||
224 | nic_data->mcdi_smem = ioremap_nocache(efx->membase_phys + | ||
225 | FR_CZ_MC_TREG_SMEM, | ||
226 | FR_CZ_MC_TREG_SMEM_STEP * | ||
227 | FR_CZ_MC_TREG_SMEM_ROWS); | ||
228 | if (!nic_data->mcdi_smem) { | ||
229 | netif_err(efx, probe, efx->net_dev, | ||
230 | "could not map MCDI at %llx+%x\n", | ||
231 | (unsigned long long)efx->membase_phys + | ||
232 | FR_CZ_MC_TREG_SMEM, | ||
233 | FR_CZ_MC_TREG_SMEM_STEP * FR_CZ_MC_TREG_SMEM_ROWS); | ||
234 | rc = -ENOMEM; | ||
235 | goto fail1; | ||
236 | } | ||
223 | efx_mcdi_init(efx); | 237 | efx_mcdi_init(efx); |
224 | 238 | ||
225 | /* Recover from a failed assertion before probing */ | 239 | /* Recover from a failed assertion before probing */ |
226 | rc = efx_mcdi_handle_assertion(efx); | 240 | rc = efx_mcdi_handle_assertion(efx); |
227 | if (rc) | 241 | if (rc) |
228 | goto fail1; | 242 | goto fail2; |
229 | 243 | ||
230 | /* Let the BMC know that the driver is now in charge of link and | 244 | /* Let the BMC know that the driver is now in charge of link and |
231 | * filter settings. We must do this before we reset the NIC */ | 245 | * filter settings. We must do this before we reset the NIC */ |
@@ -280,6 +294,7 @@ fail4: | |||
280 | fail3: | 294 | fail3: |
281 | efx_mcdi_drv_attach(efx, false, NULL); | 295 | efx_mcdi_drv_attach(efx, false, NULL); |
282 | fail2: | 296 | fail2: |
297 | iounmap(nic_data->mcdi_smem); | ||
283 | fail1: | 298 | fail1: |
284 | kfree(efx->nic_data); | 299 | kfree(efx->nic_data); |
285 | return rc; | 300 | return rc; |
@@ -359,6 +374,8 @@ static int siena_init_nic(struct efx_nic *efx) | |||
359 | 374 | ||
360 | static void siena_remove_nic(struct efx_nic *efx) | 375 | static void siena_remove_nic(struct efx_nic *efx) |
361 | { | 376 | { |
377 | struct siena_nic_data *nic_data = efx->nic_data; | ||
378 | |||
362 | efx_nic_free_buffer(efx, &efx->irq_status); | 379 | efx_nic_free_buffer(efx, &efx->irq_status); |
363 | 380 | ||
364 | siena_reset_hw(efx, RESET_TYPE_ALL); | 381 | siena_reset_hw(efx, RESET_TYPE_ALL); |
@@ -368,7 +385,8 @@ static void siena_remove_nic(struct efx_nic *efx) | |||
368 | efx_mcdi_drv_attach(efx, false, NULL); | 385 | efx_mcdi_drv_attach(efx, false, NULL); |
369 | 386 | ||
370 | /* Tear down the private nic state */ | 387 | /* Tear down the private nic state */ |
371 | kfree(efx->nic_data); | 388 | iounmap(nic_data->mcdi_smem); |
389 | kfree(nic_data); | ||
372 | efx->nic_data = NULL; | 390 | efx->nic_data = NULL; |
373 | } | 391 | } |
374 | 392 | ||
@@ -606,8 +624,7 @@ const struct efx_nic_type siena_a0_nic_type = { | |||
606 | .default_mac_ops = &efx_mcdi_mac_operations, | 624 | .default_mac_ops = &efx_mcdi_mac_operations, |
607 | 625 | ||
608 | .revision = EFX_REV_SIENA_A0, | 626 | .revision = EFX_REV_SIENA_A0, |
609 | .mem_map_size = (FR_CZ_MC_TREG_SMEM + | 627 | .mem_map_size = FR_CZ_MC_TREG_SMEM, /* MC_TREG_SMEM mapped separately */ |
610 | FR_CZ_MC_TREG_SMEM_STEP * FR_CZ_MC_TREG_SMEM_ROWS), | ||
611 | .txd_ptr_tbl_base = FR_BZ_TX_DESC_PTR_TBL, | 628 | .txd_ptr_tbl_base = FR_BZ_TX_DESC_PTR_TBL, |
612 | .rxd_ptr_tbl_base = FR_BZ_RX_DESC_PTR_TBL, | 629 | .rxd_ptr_tbl_base = FR_BZ_RX_DESC_PTR_TBL, |
613 | .buf_tbl_base = FR_BZ_BUF_FULL_TBL, | 630 | .buf_tbl_base = FR_BZ_BUF_FULL_TBL, |